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