1 /* @generated by `generate-fortify-tests.lua "signal"` */ 2 3 #define _FORTIFY_SOURCE 2 4 #define TMPFILE_SIZE (1024 * 32) 5 6 #include <sys/param.h> 7 #include <sys/jail.h> 8 #include <sys/random.h> 9 #include <sys/resource.h> 10 #include <sys/select.h> 11 #include <sys/socket.h> 12 #include <sys/time.h> 13 #include <sys/uio.h> 14 #include <sys/wait.h> 15 #include <dirent.h> 16 #include <errno.h> 17 #include <fcntl.h> 18 #include <limits.h> 19 #include <poll.h> 20 #include <signal.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <strings.h> 25 #include <sysexits.h> 26 #include <unistd.h> 27 #include <wchar.h> 28 #include <atf-c.h> 29 30 static FILE * __unused 31 new_fp(size_t __len) 32 { 33 static char fpbuf[LINE_MAX]; 34 FILE *fp; 35 36 ATF_REQUIRE(__len <= sizeof(fpbuf)); 37 38 memset(fpbuf, 'A', sizeof(fpbuf) - 1); 39 fpbuf[sizeof(fpbuf) - 1] = '\0'; 40 41 fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); 42 ATF_REQUIRE(fp != NULL); 43 44 return (fp); 45 } 46 47 /* 48 * Create a new symlink to use for readlink(2) style tests, we'll just use a 49 * random target name to have something interesting to look at. 50 */ 51 static const char * __unused 52 new_symlink(size_t __len) 53 { 54 static const char linkname[] = "link"; 55 char target[MAXNAMLEN]; 56 int error; 57 58 ATF_REQUIRE(__len <= sizeof(target)); 59 60 arc4random_buf(target, sizeof(target)); 61 62 error = unlink(linkname); 63 ATF_REQUIRE(error == 0 || errno == ENOENT); 64 65 error = symlink(target, linkname); 66 ATF_REQUIRE(error == 0); 67 68 return (linkname); 69 } 70 71 /* 72 * For our purposes, first descriptor will be the reader; we'll send both 73 * raw data and a control message over it so that the result can be used for 74 * any of our recv*() tests. 75 */ 76 static void __unused 77 new_socket(int sock[2]) 78 { 79 unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 }; 80 static char sockbuf[256]; 81 ssize_t rv; 82 size_t total = 0; 83 struct msghdr hdr = { 0 }; 84 struct cmsghdr *cmsg; 85 int error, fd; 86 87 error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); 88 ATF_REQUIRE(error == 0); 89 90 while (total != sizeof(sockbuf)) { 91 rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0); 92 93 ATF_REQUIRE_MSG(rv > 0, 94 "expected bytes sent, got %zd with %zu left (size %zu, total %zu)", 95 rv, sizeof(sockbuf) - total, sizeof(sockbuf), total); 96 ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf), 97 "%zd exceeds total %zu", rv, sizeof(sockbuf)); 98 total += rv; 99 } 100 101 hdr.msg_control = ctrl; 102 hdr.msg_controllen = sizeof(ctrl); 103 104 cmsg = CMSG_FIRSTHDR(&hdr); 105 cmsg->cmsg_level = SOL_SOCKET; 106 cmsg->cmsg_type = SCM_RIGHTS; 107 cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); 108 fd = STDIN_FILENO; 109 memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd)); 110 111 error = sendmsg(sock[1], &hdr, 0); 112 ATF_REQUIRE(error != -1); 113 } 114 115 /* 116 * Constructs a tmpfile that we can use for testing read(2) and friends. 117 */ 118 static int __unused 119 new_tmpfile(void) 120 { 121 char buf[1024]; 122 ssize_t rv; 123 size_t written; 124 int fd; 125 126 fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); 127 ATF_REQUIRE(fd >= 0); 128 129 written = 0; 130 while (written < TMPFILE_SIZE) { 131 rv = write(fd, buf, sizeof(buf)); 132 ATF_REQUIRE(rv > 0); 133 134 written += rv; 135 } 136 137 ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); 138 return (fd); 139 } 140 141 static void 142 disable_coredumps(void) 143 { 144 struct rlimit rl = { 0 }; 145 146 if (setrlimit(RLIMIT_CORE, &rl) == -1) 147 _exit(EX_OSERR); 148 } 149 150 /* 151 * Replaces stdin with a file that we can actually read from, for tests where 152 * we want a FILE * or fd that we can get data from. 153 */ 154 static void __unused 155 replace_stdin(void) 156 { 157 int fd; 158 159 fd = new_tmpfile(); 160 161 (void)dup2(fd, STDIN_FILENO); 162 if (fd != STDIN_FILENO) 163 close(fd); 164 } 165 166 ATF_TC(sig2str_before_end); 167 ATF_TC_HEAD(sig2str_before_end, tc) 168 { 169 } 170 ATF_TC_BODY(sig2str_before_end, tc) 171 { 172 #define BUF &__stack.__buf 173 struct { 174 uint8_t padding_l; 175 unsigned char __buf[SIG2STR_MAX + 1]; 176 uint8_t padding_r; 177 } __stack; 178 const size_t __bufsz __unused = sizeof(__stack.__buf); 179 const size_t __len = SIG2STR_MAX + 1; 180 const size_t __idx __unused = __len - 1; 181 182 sig2str(1, __stack.__buf); 183 #undef BUF 184 185 } 186 187 ATF_TC(sig2str_end); 188 ATF_TC_HEAD(sig2str_end, tc) 189 { 190 } 191 ATF_TC_BODY(sig2str_end, tc) 192 { 193 #define BUF &__stack.__buf 194 struct { 195 uint8_t padding_l; 196 unsigned char __buf[SIG2STR_MAX]; 197 uint8_t padding_r; 198 } __stack; 199 const size_t __bufsz __unused = sizeof(__stack.__buf); 200 const size_t __len = SIG2STR_MAX; 201 const size_t __idx __unused = __len - 1; 202 203 sig2str(1, __stack.__buf); 204 #undef BUF 205 206 } 207 208 ATF_TC(sig2str_heap_before_end); 209 ATF_TC_HEAD(sig2str_heap_before_end, tc) 210 { 211 } 212 ATF_TC_BODY(sig2str_heap_before_end, tc) 213 { 214 #define BUF __stack.__buf 215 struct { 216 uint8_t padding_l; 217 unsigned char * __buf; 218 uint8_t padding_r; 219 } __stack; 220 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (SIG2STR_MAX + 1); 221 const size_t __len = SIG2STR_MAX + 1; 222 const size_t __idx __unused = __len - 1; 223 224 __stack.__buf = malloc(__bufsz); 225 226 sig2str(1, __stack.__buf); 227 #undef BUF 228 229 } 230 231 ATF_TC(sig2str_heap_end); 232 ATF_TC_HEAD(sig2str_heap_end, tc) 233 { 234 } 235 ATF_TC_BODY(sig2str_heap_end, tc) 236 { 237 #define BUF __stack.__buf 238 struct { 239 uint8_t padding_l; 240 unsigned char * __buf; 241 uint8_t padding_r; 242 } __stack; 243 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (SIG2STR_MAX); 244 const size_t __len = SIG2STR_MAX; 245 const size_t __idx __unused = __len - 1; 246 247 __stack.__buf = malloc(__bufsz); 248 249 sig2str(1, __stack.__buf); 250 #undef BUF 251 252 } 253 254 ATF_TC(sig2str_heap_after_end); 255 ATF_TC_HEAD(sig2str_heap_after_end, tc) 256 { 257 } 258 ATF_TC_BODY(sig2str_heap_after_end, tc) 259 { 260 #define BUF __stack.__buf 261 struct { 262 uint8_t padding_l; 263 unsigned char * __buf; 264 uint8_t padding_r; 265 } __stack; 266 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (SIG2STR_MAX - 1); 267 const size_t __len = SIG2STR_MAX - 1; 268 const size_t __idx __unused = __len - 1; 269 pid_t __child; 270 int __status; 271 272 __child = fork(); 273 ATF_REQUIRE(__child >= 0); 274 if (__child > 0) 275 goto monitor; 276 277 /* Child */ 278 disable_coredumps(); 279 __stack.__buf = malloc(__bufsz); 280 281 sig2str(1, __stack.__buf); 282 _exit(EX_SOFTWARE); /* Should have aborted. */ 283 284 monitor: 285 while (waitpid(__child, &__status, 0) != __child) { 286 ATF_REQUIRE_EQ(EINTR, errno); 287 } 288 289 if (!WIFSIGNALED(__status)) { 290 switch (WEXITSTATUS(__status)) { 291 case EX_SOFTWARE: 292 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 293 break; 294 case EX_OSERR: 295 atf_tc_fail("setrlimit(2) failed"); 296 break; 297 default: 298 atf_tc_fail("child exited with status %d", 299 WEXITSTATUS(__status)); 300 } 301 } else { 302 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 303 } 304 #undef BUF 305 306 } 307 308 ATF_TP_ADD_TCS(tp) 309 { 310 ATF_TP_ADD_TC(tp, sig2str_before_end); 311 ATF_TP_ADD_TC(tp, sig2str_end); 312 ATF_TP_ADD_TC(tp, sig2str_heap_before_end); 313 ATF_TP_ADD_TC(tp, sig2str_heap_end); 314 ATF_TP_ADD_TC(tp, sig2str_heap_after_end); 315 return (atf_no_error()); 316 } 317