Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/tests/secure/fortify_poll_test.c
39553 views
1
/* @generated by `generate-fortify-tests.lua "poll"` */
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(poll_before_end);
167
ATF_TC_HEAD(poll_before_end, tc)
168
{
169
}
170
ATF_TC_BODY(poll_before_end, tc)
171
{
172
#define BUF &__stack.__buf
173
struct {
174
uint8_t padding_l;
175
struct pollfd __buf[4];
176
uint8_t padding_r;
177
} __stack;
178
const size_t __bufsz __unused = sizeof(__stack.__buf);
179
const size_t __len = 4 - 1;
180
const size_t __idx __unused = __len - 1;
181
182
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
183
__stack.__buf[i].fd = -1;
184
}
185
186
poll(__stack.__buf, __len, 0);
187
#undef BUF
188
189
}
190
191
ATF_TC(poll_end);
192
ATF_TC_HEAD(poll_end, tc)
193
{
194
}
195
ATF_TC_BODY(poll_end, tc)
196
{
197
#define BUF &__stack.__buf
198
struct {
199
uint8_t padding_l;
200
struct pollfd __buf[4];
201
uint8_t padding_r;
202
} __stack;
203
const size_t __bufsz __unused = sizeof(__stack.__buf);
204
const size_t __len = 4;
205
const size_t __idx __unused = __len - 1;
206
207
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
208
__stack.__buf[i].fd = -1;
209
}
210
211
poll(__stack.__buf, __len, 0);
212
#undef BUF
213
214
}
215
216
ATF_TC(poll_after_end);
217
ATF_TC_HEAD(poll_after_end, tc)
218
{
219
}
220
ATF_TC_BODY(poll_after_end, tc)
221
{
222
#define BUF &__stack.__buf
223
struct {
224
uint8_t padding_l;
225
struct pollfd __buf[4];
226
uint8_t padding_r;
227
} __stack;
228
const size_t __bufsz __unused = sizeof(__stack.__buf);
229
const size_t __len = 4 + 1;
230
const size_t __idx __unused = __len - 1;
231
pid_t __child;
232
int __status;
233
234
__child = fork();
235
ATF_REQUIRE(__child >= 0);
236
if (__child > 0)
237
goto monitor;
238
239
/* Child */
240
disable_coredumps();
241
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
242
__stack.__buf[i].fd = -1;
243
}
244
245
poll(__stack.__buf, __len, 0);
246
_exit(EX_SOFTWARE); /* Should have aborted. */
247
248
monitor:
249
while (waitpid(__child, &__status, 0) != __child) {
250
ATF_REQUIRE_EQ(EINTR, errno);
251
}
252
253
if (!WIFSIGNALED(__status)) {
254
switch (WEXITSTATUS(__status)) {
255
case EX_SOFTWARE:
256
atf_tc_fail("FORTIFY_SOURCE failed to abort");
257
break;
258
case EX_OSERR:
259
atf_tc_fail("setrlimit(2) failed");
260
break;
261
default:
262
atf_tc_fail("child exited with status %d",
263
WEXITSTATUS(__status));
264
}
265
} else {
266
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
267
}
268
#undef BUF
269
270
}
271
272
ATF_TC(poll_heap_before_end);
273
ATF_TC_HEAD(poll_heap_before_end, tc)
274
{
275
}
276
ATF_TC_BODY(poll_heap_before_end, tc)
277
{
278
#define BUF __stack.__buf
279
struct {
280
uint8_t padding_l;
281
struct pollfd * __buf;
282
uint8_t padding_r;
283
} __stack;
284
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
285
const size_t __len = 4 - 1;
286
const size_t __idx __unused = __len - 1;
287
288
__stack.__buf = malloc(__bufsz);
289
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
290
__stack.__buf[i].fd = -1;
291
}
292
293
poll(__stack.__buf, __len, 0);
294
#undef BUF
295
296
}
297
298
ATF_TC(poll_heap_end);
299
ATF_TC_HEAD(poll_heap_end, tc)
300
{
301
}
302
ATF_TC_BODY(poll_heap_end, tc)
303
{
304
#define BUF __stack.__buf
305
struct {
306
uint8_t padding_l;
307
struct pollfd * __buf;
308
uint8_t padding_r;
309
} __stack;
310
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
311
const size_t __len = 4;
312
const size_t __idx __unused = __len - 1;
313
314
__stack.__buf = malloc(__bufsz);
315
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
316
__stack.__buf[i].fd = -1;
317
}
318
319
poll(__stack.__buf, __len, 0);
320
#undef BUF
321
322
}
323
324
ATF_TC(poll_heap_after_end);
325
ATF_TC_HEAD(poll_heap_after_end, tc)
326
{
327
}
328
ATF_TC_BODY(poll_heap_after_end, tc)
329
{
330
#define BUF __stack.__buf
331
struct {
332
uint8_t padding_l;
333
struct pollfd * __buf;
334
uint8_t padding_r;
335
} __stack;
336
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
337
const size_t __len = 4 + 1;
338
const size_t __idx __unused = __len - 1;
339
pid_t __child;
340
int __status;
341
342
__child = fork();
343
ATF_REQUIRE(__child >= 0);
344
if (__child > 0)
345
goto monitor;
346
347
/* Child */
348
disable_coredumps();
349
__stack.__buf = malloc(__bufsz);
350
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
351
__stack.__buf[i].fd = -1;
352
}
353
354
poll(__stack.__buf, __len, 0);
355
_exit(EX_SOFTWARE); /* Should have aborted. */
356
357
monitor:
358
while (waitpid(__child, &__status, 0) != __child) {
359
ATF_REQUIRE_EQ(EINTR, errno);
360
}
361
362
if (!WIFSIGNALED(__status)) {
363
switch (WEXITSTATUS(__status)) {
364
case EX_SOFTWARE:
365
atf_tc_fail("FORTIFY_SOURCE failed to abort");
366
break;
367
case EX_OSERR:
368
atf_tc_fail("setrlimit(2) failed");
369
break;
370
default:
371
atf_tc_fail("child exited with status %d",
372
WEXITSTATUS(__status));
373
}
374
} else {
375
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
376
}
377
#undef BUF
378
379
}
380
381
ATF_TC(ppoll_before_end);
382
ATF_TC_HEAD(ppoll_before_end, tc)
383
{
384
}
385
ATF_TC_BODY(ppoll_before_end, tc)
386
{
387
#define BUF &__stack.__buf
388
struct {
389
uint8_t padding_l;
390
struct pollfd __buf[4];
391
uint8_t padding_r;
392
} __stack;
393
const size_t __bufsz __unused = sizeof(__stack.__buf);
394
const size_t __len = 4 - 1;
395
const size_t __idx __unused = __len - 1;
396
struct timespec tv = { 0 };
397
398
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
399
__stack.__buf[i].fd = -1;
400
}
401
402
ppoll(__stack.__buf, __len, &tv, NULL);
403
#undef BUF
404
405
}
406
407
ATF_TC(ppoll_end);
408
ATF_TC_HEAD(ppoll_end, tc)
409
{
410
}
411
ATF_TC_BODY(ppoll_end, tc)
412
{
413
#define BUF &__stack.__buf
414
struct {
415
uint8_t padding_l;
416
struct pollfd __buf[4];
417
uint8_t padding_r;
418
} __stack;
419
const size_t __bufsz __unused = sizeof(__stack.__buf);
420
const size_t __len = 4;
421
const size_t __idx __unused = __len - 1;
422
struct timespec tv = { 0 };
423
424
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
425
__stack.__buf[i].fd = -1;
426
}
427
428
ppoll(__stack.__buf, __len, &tv, NULL);
429
#undef BUF
430
431
}
432
433
ATF_TC(ppoll_after_end);
434
ATF_TC_HEAD(ppoll_after_end, tc)
435
{
436
}
437
ATF_TC_BODY(ppoll_after_end, tc)
438
{
439
#define BUF &__stack.__buf
440
struct {
441
uint8_t padding_l;
442
struct pollfd __buf[4];
443
uint8_t padding_r;
444
} __stack;
445
const size_t __bufsz __unused = sizeof(__stack.__buf);
446
const size_t __len = 4 + 1;
447
const size_t __idx __unused = __len - 1;
448
pid_t __child;
449
int __status;
450
struct timespec tv = { 0 };
451
452
__child = fork();
453
ATF_REQUIRE(__child >= 0);
454
if (__child > 0)
455
goto monitor;
456
457
/* Child */
458
disable_coredumps();
459
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
460
__stack.__buf[i].fd = -1;
461
}
462
463
ppoll(__stack.__buf, __len, &tv, NULL);
464
_exit(EX_SOFTWARE); /* Should have aborted. */
465
466
monitor:
467
while (waitpid(__child, &__status, 0) != __child) {
468
ATF_REQUIRE_EQ(EINTR, errno);
469
}
470
471
if (!WIFSIGNALED(__status)) {
472
switch (WEXITSTATUS(__status)) {
473
case EX_SOFTWARE:
474
atf_tc_fail("FORTIFY_SOURCE failed to abort");
475
break;
476
case EX_OSERR:
477
atf_tc_fail("setrlimit(2) failed");
478
break;
479
default:
480
atf_tc_fail("child exited with status %d",
481
WEXITSTATUS(__status));
482
}
483
} else {
484
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
485
}
486
#undef BUF
487
488
}
489
490
ATF_TC(ppoll_heap_before_end);
491
ATF_TC_HEAD(ppoll_heap_before_end, tc)
492
{
493
}
494
ATF_TC_BODY(ppoll_heap_before_end, tc)
495
{
496
#define BUF __stack.__buf
497
struct {
498
uint8_t padding_l;
499
struct pollfd * __buf;
500
uint8_t padding_r;
501
} __stack;
502
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
503
const size_t __len = 4 - 1;
504
const size_t __idx __unused = __len - 1;
505
struct timespec tv = { 0 };
506
507
__stack.__buf = malloc(__bufsz);
508
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
509
__stack.__buf[i].fd = -1;
510
}
511
512
ppoll(__stack.__buf, __len, &tv, NULL);
513
#undef BUF
514
515
}
516
517
ATF_TC(ppoll_heap_end);
518
ATF_TC_HEAD(ppoll_heap_end, tc)
519
{
520
}
521
ATF_TC_BODY(ppoll_heap_end, tc)
522
{
523
#define BUF __stack.__buf
524
struct {
525
uint8_t padding_l;
526
struct pollfd * __buf;
527
uint8_t padding_r;
528
} __stack;
529
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
530
const size_t __len = 4;
531
const size_t __idx __unused = __len - 1;
532
struct timespec tv = { 0 };
533
534
__stack.__buf = malloc(__bufsz);
535
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
536
__stack.__buf[i].fd = -1;
537
}
538
539
ppoll(__stack.__buf, __len, &tv, NULL);
540
#undef BUF
541
542
}
543
544
ATF_TC(ppoll_heap_after_end);
545
ATF_TC_HEAD(ppoll_heap_after_end, tc)
546
{
547
}
548
ATF_TC_BODY(ppoll_heap_after_end, tc)
549
{
550
#define BUF __stack.__buf
551
struct {
552
uint8_t padding_l;
553
struct pollfd * __buf;
554
uint8_t padding_r;
555
} __stack;
556
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
557
const size_t __len = 4 + 1;
558
const size_t __idx __unused = __len - 1;
559
pid_t __child;
560
int __status;
561
struct timespec tv = { 0 };
562
563
__child = fork();
564
ATF_REQUIRE(__child >= 0);
565
if (__child > 0)
566
goto monitor;
567
568
/* Child */
569
disable_coredumps();
570
__stack.__buf = malloc(__bufsz);
571
for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
572
__stack.__buf[i].fd = -1;
573
}
574
575
ppoll(__stack.__buf, __len, &tv, NULL);
576
_exit(EX_SOFTWARE); /* Should have aborted. */
577
578
monitor:
579
while (waitpid(__child, &__status, 0) != __child) {
580
ATF_REQUIRE_EQ(EINTR, errno);
581
}
582
583
if (!WIFSIGNALED(__status)) {
584
switch (WEXITSTATUS(__status)) {
585
case EX_SOFTWARE:
586
atf_tc_fail("FORTIFY_SOURCE failed to abort");
587
break;
588
case EX_OSERR:
589
atf_tc_fail("setrlimit(2) failed");
590
break;
591
default:
592
atf_tc_fail("child exited with status %d",
593
WEXITSTATUS(__status));
594
}
595
} else {
596
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
597
}
598
#undef BUF
599
600
}
601
602
ATF_TP_ADD_TCS(tp)
603
{
604
ATF_TP_ADD_TC(tp, poll_before_end);
605
ATF_TP_ADD_TC(tp, poll_end);
606
ATF_TP_ADD_TC(tp, poll_after_end);
607
ATF_TP_ADD_TC(tp, poll_heap_before_end);
608
ATF_TP_ADD_TC(tp, poll_heap_end);
609
ATF_TP_ADD_TC(tp, poll_heap_after_end);
610
ATF_TP_ADD_TC(tp, ppoll_before_end);
611
ATF_TP_ADD_TC(tp, ppoll_end);
612
ATF_TP_ADD_TC(tp, ppoll_after_end);
613
ATF_TP_ADD_TC(tp, ppoll_heap_before_end);
614
ATF_TP_ADD_TC(tp, ppoll_heap_end);
615
ATF_TP_ADD_TC(tp, ppoll_heap_after_end);
616
return (atf_no_error());
617
}
618
619