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