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