1 /* @generated by `generate-fortify-tests.lua "stdlib"` */ 2 3 #define _FORTIFY_SOURCE 2 4 #define TMPFILE_SIZE (1024 * 32) 5 6 #include <sys/param.h> 7 #include <sys/random.h> 8 #include <sys/resource.h> 9 #include <sys/time.h> 10 #include <sys/wait.h> 11 #include <dirent.h> 12 #include <errno.h> 13 #include <fcntl.h> 14 #include <limits.h> 15 #include <poll.h> 16 #include <signal.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <strings.h> 21 #include <sysexits.h> 22 #include <unistd.h> 23 #include <wchar.h> 24 #include <atf-c.h> 25 26 static FILE * __unused 27 new_fp(size_t __len) 28 { 29 static char fpbuf[LINE_MAX]; 30 FILE *fp; 31 32 ATF_REQUIRE(__len <= sizeof(fpbuf)); 33 34 memset(fpbuf, 'A', sizeof(fpbuf) - 1); 35 fpbuf[sizeof(fpbuf) - 1] = '\0'; 36 37 fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); 38 ATF_REQUIRE(fp != NULL); 39 40 return (fp); 41 } 42 43 /* 44 * Create a new symlink to use for readlink(2) style tests, we'll just use a 45 * random target name to have something interesting to look at. 46 */ 47 static const char * __unused 48 new_symlink(size_t __len) 49 { 50 static const char linkname[] = "link"; 51 char target[MAXNAMLEN]; 52 int error; 53 54 ATF_REQUIRE(__len <= sizeof(target)); 55 56 arc4random_buf(target, sizeof(target)); 57 58 error = unlink(linkname); 59 ATF_REQUIRE(error == 0 || errno == ENOENT); 60 61 error = symlink(target, linkname); 62 ATF_REQUIRE(error == 0); 63 64 return (linkname); 65 } 66 67 /* 68 * Constructs a tmpfile that we can use for testing read(2) and friends. 69 */ 70 static int __unused 71 new_tmpfile(void) 72 { 73 char buf[1024]; 74 ssize_t rv; 75 size_t written; 76 int fd; 77 78 fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); 79 ATF_REQUIRE(fd >= 0); 80 81 written = 0; 82 while (written < TMPFILE_SIZE) { 83 rv = write(fd, buf, sizeof(buf)); 84 ATF_REQUIRE(rv > 0); 85 86 written += rv; 87 } 88 89 ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); 90 return (fd); 91 } 92 93 static void 94 disable_coredumps(void) 95 { 96 struct rlimit rl = { 0 }; 97 98 if (setrlimit(RLIMIT_CORE, &rl) == -1) 99 _exit(EX_OSERR); 100 } 101 102 /* 103 * Replaces stdin with a file that we can actually read from, for tests where 104 * we want a FILE * or fd that we can get data from. 105 */ 106 static void __unused 107 replace_stdin(void) 108 { 109 int fd; 110 111 fd = new_tmpfile(); 112 113 (void)dup2(fd, STDIN_FILENO); 114 if (fd != STDIN_FILENO) 115 close(fd); 116 } 117 118 ATF_TC_WITHOUT_HEAD(arc4random_buf_before_end); 119 ATF_TC_BODY(arc4random_buf_before_end, tc) 120 { 121 #define BUF &__stack.__buf 122 struct { 123 uint8_t padding_l; 124 unsigned char __buf[42]; 125 uint8_t padding_r; 126 } __stack; 127 const size_t __bufsz __unused = sizeof(__stack.__buf); 128 const size_t __len = 42 - 1; 129 const size_t __idx __unused = __len - 1; 130 131 arc4random_buf(__stack.__buf, __len); 132 #undef BUF 133 134 } 135 136 ATF_TC_WITHOUT_HEAD(arc4random_buf_end); 137 ATF_TC_BODY(arc4random_buf_end, tc) 138 { 139 #define BUF &__stack.__buf 140 struct { 141 uint8_t padding_l; 142 unsigned char __buf[42]; 143 uint8_t padding_r; 144 } __stack; 145 const size_t __bufsz __unused = sizeof(__stack.__buf); 146 const size_t __len = 42; 147 const size_t __idx __unused = __len - 1; 148 149 arc4random_buf(__stack.__buf, __len); 150 #undef BUF 151 152 } 153 154 ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_before_end); 155 ATF_TC_BODY(arc4random_buf_heap_before_end, tc) 156 { 157 #define BUF __stack.__buf 158 struct { 159 uint8_t padding_l; 160 unsigned char * __buf; 161 uint8_t padding_r; 162 } __stack; 163 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 164 const size_t __len = 42 - 1; 165 const size_t __idx __unused = __len - 1; 166 167 __stack.__buf = malloc(__bufsz); 168 169 arc4random_buf(__stack.__buf, __len); 170 #undef BUF 171 172 } 173 174 ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_end); 175 ATF_TC_BODY(arc4random_buf_heap_end, tc) 176 { 177 #define BUF __stack.__buf 178 struct { 179 uint8_t padding_l; 180 unsigned char * __buf; 181 uint8_t padding_r; 182 } __stack; 183 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 184 const size_t __len = 42; 185 const size_t __idx __unused = __len - 1; 186 187 __stack.__buf = malloc(__bufsz); 188 189 arc4random_buf(__stack.__buf, __len); 190 #undef BUF 191 192 } 193 194 ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_after_end); 195 ATF_TC_BODY(arc4random_buf_heap_after_end, tc) 196 { 197 #define BUF __stack.__buf 198 struct { 199 uint8_t padding_l; 200 unsigned char * __buf; 201 uint8_t padding_r; 202 } __stack; 203 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 204 const size_t __len = 42 + 1; 205 const size_t __idx __unused = __len - 1; 206 pid_t __child; 207 int __status; 208 209 __child = fork(); 210 ATF_REQUIRE(__child >= 0); 211 if (__child > 0) 212 goto monitor; 213 214 /* Child */ 215 disable_coredumps(); 216 __stack.__buf = malloc(__bufsz); 217 218 arc4random_buf(__stack.__buf, __len); 219 _exit(EX_SOFTWARE); /* Should have aborted. */ 220 221 monitor: 222 while (waitpid(__child, &__status, 0) != __child) { 223 ATF_REQUIRE_EQ(EINTR, errno); 224 } 225 226 if (!WIFSIGNALED(__status)) { 227 switch (WEXITSTATUS(__status)) { 228 case EX_SOFTWARE: 229 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 230 break; 231 case EX_OSERR: 232 atf_tc_fail("setrlimit(2) failed"); 233 break; 234 default: 235 atf_tc_fail("child exited with status %d", 236 WEXITSTATUS(__status)); 237 } 238 } else { 239 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 240 } 241 #undef BUF 242 243 } 244 245 ATF_TC_WITHOUT_HEAD(realpath_before_end); 246 ATF_TC_BODY(realpath_before_end, tc) 247 { 248 #define BUF &__stack.__buf 249 struct { 250 uint8_t padding_l; 251 unsigned char __buf[PATH_MAX + 1]; 252 uint8_t padding_r; 253 } __stack; 254 const size_t __bufsz __unused = sizeof(__stack.__buf); 255 const size_t __len = PATH_MAX + 1; 256 const size_t __idx __unused = __len - 1; 257 258 realpath(".", __stack.__buf); 259 #undef BUF 260 261 } 262 263 ATF_TC_WITHOUT_HEAD(realpath_end); 264 ATF_TC_BODY(realpath_end, tc) 265 { 266 #define BUF &__stack.__buf 267 struct { 268 uint8_t padding_l; 269 unsigned char __buf[PATH_MAX]; 270 uint8_t padding_r; 271 } __stack; 272 const size_t __bufsz __unused = sizeof(__stack.__buf); 273 const size_t __len = PATH_MAX; 274 const size_t __idx __unused = __len - 1; 275 276 realpath(".", __stack.__buf); 277 #undef BUF 278 279 } 280 281 ATF_TC_WITHOUT_HEAD(realpath_heap_before_end); 282 ATF_TC_BODY(realpath_heap_before_end, tc) 283 { 284 #define BUF __stack.__buf 285 struct { 286 uint8_t padding_l; 287 unsigned char * __buf; 288 uint8_t padding_r; 289 } __stack; 290 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX + 1); 291 const size_t __len = PATH_MAX + 1; 292 const size_t __idx __unused = __len - 1; 293 294 __stack.__buf = malloc(__bufsz); 295 296 realpath(".", __stack.__buf); 297 #undef BUF 298 299 } 300 301 ATF_TC_WITHOUT_HEAD(realpath_heap_end); 302 ATF_TC_BODY(realpath_heap_end, tc) 303 { 304 #define BUF __stack.__buf 305 struct { 306 uint8_t padding_l; 307 unsigned char * __buf; 308 uint8_t padding_r; 309 } __stack; 310 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX); 311 const size_t __len = PATH_MAX; 312 const size_t __idx __unused = __len - 1; 313 314 __stack.__buf = malloc(__bufsz); 315 316 realpath(".", __stack.__buf); 317 #undef BUF 318 319 } 320 321 ATF_TC_WITHOUT_HEAD(realpath_heap_after_end); 322 ATF_TC_BODY(realpath_heap_after_end, tc) 323 { 324 #define BUF __stack.__buf 325 struct { 326 uint8_t padding_l; 327 unsigned char * __buf; 328 uint8_t padding_r; 329 } __stack; 330 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX - 1); 331 const size_t __len = PATH_MAX - 1; 332 const size_t __idx __unused = __len - 1; 333 pid_t __child; 334 int __status; 335 336 __child = fork(); 337 ATF_REQUIRE(__child >= 0); 338 if (__child > 0) 339 goto monitor; 340 341 /* Child */ 342 disable_coredumps(); 343 __stack.__buf = malloc(__bufsz); 344 345 realpath(".", __stack.__buf); 346 _exit(EX_SOFTWARE); /* Should have aborted. */ 347 348 monitor: 349 while (waitpid(__child, &__status, 0) != __child) { 350 ATF_REQUIRE_EQ(EINTR, errno); 351 } 352 353 if (!WIFSIGNALED(__status)) { 354 switch (WEXITSTATUS(__status)) { 355 case EX_SOFTWARE: 356 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 357 break; 358 case EX_OSERR: 359 atf_tc_fail("setrlimit(2) failed"); 360 break; 361 default: 362 atf_tc_fail("child exited with status %d", 363 WEXITSTATUS(__status)); 364 } 365 } else { 366 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 367 } 368 #undef BUF 369 370 } 371 372 ATF_TP_ADD_TCS(tp) 373 { 374 ATF_TP_ADD_TC(tp, arc4random_buf_before_end); 375 ATF_TP_ADD_TC(tp, arc4random_buf_end); 376 ATF_TP_ADD_TC(tp, arc4random_buf_heap_before_end); 377 ATF_TP_ADD_TC(tp, arc4random_buf_heap_end); 378 ATF_TP_ADD_TC(tp, arc4random_buf_heap_after_end); 379 ATF_TP_ADD_TC(tp, realpath_before_end); 380 ATF_TP_ADD_TC(tp, realpath_end); 381 ATF_TP_ADD_TC(tp, realpath_heap_before_end); 382 ATF_TP_ADD_TC(tp, realpath_heap_end); 383 ATF_TP_ADD_TC(tp, realpath_heap_after_end); 384 return (atf_no_error()); 385 } 386