xref: /freebsd/tests/sys/audit/file-attribute-access.c (revision cd9cc48b9affbd920825c1b2d26a1eae151249b8)
1 /*-
2  * Copyright (c) 2018 Aniket Pandey
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * SUCH DAMAGE.
24  *
25  * $FreeBSD$
26  */
27 
28 #include <sys/param.h>
29 #include <sys/ucred.h>
30 #include <sys/mount.h>
31 #include <sys/stat.h>
32 #include <sys/syscall.h>
33 
34 #include <atf-c.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 
38 #include "utils.h"
39 
40 static struct pollfd fds[1];
41 static mode_t mode = 0777;
42 static pid_t pid;
43 static fhandle_t fht;
44 static int filedesc, fhdesc;
45 static char extregex[80];
46 static struct stat statbuff;
47 static struct statfs statfsbuff;
48 static const char *auclass = "fa";
49 static const char *path = "fileforaudit";
50 static const char *errpath = "dirdoesnotexist/fileforaudit";
51 static const char *successreg = "fileforaudit.*return,success";
52 static const char *failurereg = "fileforaudit.*return,failure";
53 
54 
55 ATF_TC_WITH_CLEANUP(stat_success);
56 ATF_TC_HEAD(stat_success, tc)
57 {
58 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
59 					"stat(2) call");
60 }
61 
62 ATF_TC_BODY(stat_success, tc)
63 {
64 	/* File needs to exist to call stat(2) */
65 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
66 	FILE *pipefd = setup(fds, auclass);
67 	ATF_REQUIRE_EQ(0, stat(path, &statbuff));
68 	check_audit(fds, successreg, pipefd);
69 	close(filedesc);
70 }
71 
72 ATF_TC_CLEANUP(stat_success, tc)
73 {
74 	cleanup();
75 }
76 
77 
78 ATF_TC_WITH_CLEANUP(stat_failure);
79 ATF_TC_HEAD(stat_failure, tc)
80 {
81 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
82 					"stat(2) call");
83 }
84 
85 ATF_TC_BODY(stat_failure, tc)
86 {
87 	FILE *pipefd = setup(fds, auclass);
88 	/* Failure reason: file does not exist */
89 	ATF_REQUIRE_EQ(-1, stat(errpath, &statbuff));
90 	check_audit(fds, failurereg, pipefd);
91 }
92 
93 ATF_TC_CLEANUP(stat_failure, tc)
94 {
95 	cleanup();
96 }
97 
98 
99 ATF_TC_WITH_CLEANUP(lstat_success);
100 ATF_TC_HEAD(lstat_success, tc)
101 {
102 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
103 					"lstat(2) call");
104 }
105 
106 ATF_TC_BODY(lstat_success, tc)
107 {
108 	/* Symbolic link needs to exist to call lstat(2) */
109 	ATF_REQUIRE_EQ(0, symlink("symlink", path));
110 	FILE *pipefd = setup(fds, auclass);
111 	ATF_REQUIRE_EQ(0, lstat(path, &statbuff));
112 	check_audit(fds, successreg, pipefd);
113 }
114 
115 ATF_TC_CLEANUP(lstat_success, tc)
116 {
117 	cleanup();
118 }
119 
120 
121 ATF_TC_WITH_CLEANUP(lstat_failure);
122 ATF_TC_HEAD(lstat_failure, tc)
123 {
124 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
125 					"lstat(2) call");
126 }
127 
128 ATF_TC_BODY(lstat_failure, tc)
129 {
130 	FILE *pipefd = setup(fds, auclass);
131 	/* Failure reason: symbolic link does not exist */
132 	ATF_REQUIRE_EQ(-1, lstat(errpath, &statbuff));
133 	check_audit(fds, failurereg, pipefd);
134 }
135 
136 ATF_TC_CLEANUP(lstat_failure, tc)
137 {
138 	cleanup();
139 }
140 
141 
142 ATF_TC_WITH_CLEANUP(fstat_success);
143 ATF_TC_HEAD(fstat_success, tc)
144 {
145 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
146 					"fstat(2) call");
147 }
148 
149 ATF_TC_BODY(fstat_success, tc)
150 {
151 	/* File needs to exist to call fstat(2) */
152 	ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1);
153 	FILE *pipefd = setup(fds, auclass);
154 	ATF_REQUIRE_EQ(0, fstat(filedesc, &statbuff));
155 
156 	snprintf(extregex, sizeof(extregex),
157 		"fstat.*%jd.*return,success", (intmax_t)statbuff.st_ino);
158 	check_audit(fds, extregex, pipefd);
159 	close(filedesc);
160 }
161 
162 ATF_TC_CLEANUP(fstat_success, tc)
163 {
164 	cleanup();
165 }
166 
167 
168 ATF_TC_WITH_CLEANUP(fstat_failure);
169 ATF_TC_HEAD(fstat_failure, tc)
170 {
171 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
172 					"fstat(2) call");
173 }
174 
175 ATF_TC_BODY(fstat_failure, tc)
176 {
177 	FILE *pipefd = setup(fds, auclass);
178 	const char *regex = "fstat.*return,failure : Bad file descriptor";
179 	/* Failure reason: bad file descriptor */
180 	ATF_REQUIRE_EQ(-1, fstat(-1, &statbuff));
181 	check_audit(fds, regex, pipefd);
182 }
183 
184 ATF_TC_CLEANUP(fstat_failure, tc)
185 {
186 	cleanup();
187 }
188 
189 
190 ATF_TC_WITH_CLEANUP(fstatat_success);
191 ATF_TC_HEAD(fstatat_success, tc)
192 {
193 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
194 					"fstatat(2) call");
195 }
196 
197 ATF_TC_BODY(fstatat_success, tc)
198 {
199 	/* File or Symbolic link needs to exist to call lstat(2) */
200 	ATF_REQUIRE_EQ(0, symlink("symlink", path));
201 	FILE *pipefd = setup(fds, auclass);
202 	ATF_REQUIRE_EQ(0, fstatat(AT_FDCWD, path, &statbuff,
203 		AT_SYMLINK_NOFOLLOW));
204 	check_audit(fds, successreg, pipefd);
205 }
206 
207 ATF_TC_CLEANUP(fstatat_success, tc)
208 {
209 	cleanup();
210 }
211 
212 
213 ATF_TC_WITH_CLEANUP(fstatat_failure);
214 ATF_TC_HEAD(fstatat_failure, tc)
215 {
216 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
217 					"fstatat(2) call");
218 }
219 
220 ATF_TC_BODY(fstatat_failure, tc)
221 {
222 	FILE *pipefd = setup(fds, auclass);
223 	/* Failure reason: symbolic link does not exist */
224 	ATF_REQUIRE_EQ(-1, fstatat(AT_FDCWD, path, &statbuff,
225 		AT_SYMLINK_NOFOLLOW));
226 	check_audit(fds, failurereg, pipefd);
227 }
228 
229 ATF_TC_CLEANUP(fstatat_failure, tc)
230 {
231 	cleanup();
232 }
233 
234 
235 ATF_TC_WITH_CLEANUP(statfs_success);
236 ATF_TC_HEAD(statfs_success, tc)
237 {
238 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
239 					"statfs(2) call");
240 }
241 
242 ATF_TC_BODY(statfs_success, tc)
243 {
244 	/* File needs to exist to call statfs(2) */
245 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
246 	FILE *pipefd = setup(fds, auclass);
247 	ATF_REQUIRE_EQ(0, statfs(path, &statfsbuff));
248 	check_audit(fds, successreg, pipefd);
249 	close(filedesc);
250 }
251 
252 ATF_TC_CLEANUP(statfs_success, tc)
253 {
254 	cleanup();
255 }
256 
257 
258 ATF_TC_WITH_CLEANUP(statfs_failure);
259 ATF_TC_HEAD(statfs_failure, tc)
260 {
261 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
262 					"statfs(2) call");
263 }
264 
265 ATF_TC_BODY(statfs_failure, tc)
266 {
267 	FILE *pipefd = setup(fds, auclass);
268 	/* Failure reason: file does not exist */
269 	ATF_REQUIRE_EQ(-1, statfs(errpath, &statfsbuff));
270 	check_audit(fds, failurereg, pipefd);
271 }
272 
273 ATF_TC_CLEANUP(statfs_failure, tc)
274 {
275 	cleanup();
276 }
277 
278 
279 ATF_TC_WITH_CLEANUP(fstatfs_success);
280 ATF_TC_HEAD(fstatfs_success, tc)
281 {
282 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
283 					"fstatfs(2) call");
284 }
285 
286 ATF_TC_BODY(fstatfs_success, tc)
287 {
288 	/* File needs to exist to call fstat(2) */
289 	ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1);
290 	/* Call stat(2) to store the Inode number of 'path' */
291 	ATF_REQUIRE_EQ(0, stat(path, &statbuff));
292 	FILE *pipefd = setup(fds, auclass);
293 	ATF_REQUIRE_EQ(0, fstatfs(filedesc, &statfsbuff));
294 
295 	snprintf(extregex, sizeof(extregex), "fstatfs.*%jd.*return,success",
296 			(intmax_t)statbuff.st_ino);
297 	check_audit(fds, extregex, pipefd);
298 	close(filedesc);
299 }
300 
301 ATF_TC_CLEANUP(fstatfs_success, tc)
302 {
303 	cleanup();
304 }
305 
306 
307 ATF_TC_WITH_CLEANUP(fstatfs_failure);
308 ATF_TC_HEAD(fstatfs_failure, tc)
309 {
310 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
311 					"fstatfs(2) call");
312 }
313 
314 ATF_TC_BODY(fstatfs_failure, tc)
315 {
316 	FILE *pipefd = setup(fds, auclass);
317 	const char *regex = "fstatfs.*return,failure : Bad file descriptor";
318 	/* Failure reason: bad file descriptor */
319 	ATF_REQUIRE_EQ(-1, fstatfs(-1, &statfsbuff));
320 	check_audit(fds, regex, pipefd);
321 }
322 
323 ATF_TC_CLEANUP(fstatfs_failure, tc)
324 {
325 	cleanup();
326 }
327 
328 
329 ATF_TC_WITH_CLEANUP(getfsstat_success);
330 ATF_TC_HEAD(getfsstat_success, tc)
331 {
332 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
333 					"getfsstat(2) call");
334 }
335 
336 ATF_TC_BODY(getfsstat_success, tc)
337 {
338 	pid = getpid();
339 	snprintf(extregex, sizeof(extregex), "getfsstat.*%d.*success", pid);
340 
341 	FILE *pipefd = setup(fds, auclass);
342 	ATF_REQUIRE(getfsstat(NULL, 0, MNT_NOWAIT) != -1);
343 	check_audit(fds, extregex, pipefd);
344 }
345 
346 ATF_TC_CLEANUP(getfsstat_success, tc)
347 {
348 	cleanup();
349 }
350 
351 
352 ATF_TC_WITH_CLEANUP(getfsstat_failure);
353 ATF_TC_HEAD(getfsstat_failure, tc)
354 {
355 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
356 					"getfsstat(2) call");
357 }
358 
359 ATF_TC_BODY(getfsstat_failure, tc)
360 {
361 	const char *regex = "getfsstat.*return,failure : Invalid argument";
362 	FILE *pipefd = setup(fds, auclass);
363 	/* Failure reason: Invalid value for mode */
364 	ATF_REQUIRE_EQ(-1, getfsstat(NULL, 0, -1));
365 	check_audit(fds, regex, pipefd);
366 }
367 
368 ATF_TC_CLEANUP(getfsstat_failure, tc)
369 {
370 	cleanup();
371 }
372 
373 
374 ATF_TC_WITH_CLEANUP(fhopen_success);
375 ATF_TC_HEAD(fhopen_success, tc)
376 {
377 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
378 					"fhopen(2) call");
379 }
380 
381 ATF_TC_BODY(fhopen_success, tc)
382 {
383 	pid = getpid();
384 	snprintf(extregex, sizeof(extregex), "fhopen.*%d.*return,success", pid);
385 
386 	/* File needs to exist to get a file-handle */
387 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
388 	/* Get the file handle to be passed to fhopen(2) */
389 	ATF_REQUIRE_EQ(0, getfh(path, &fht));
390 
391 	FILE *pipefd = setup(fds, auclass);
392 	ATF_REQUIRE((fhdesc = fhopen(&fht, O_RDWR)) != -1);
393 	check_audit(fds, extregex, pipefd);
394 
395 	close(fhdesc);
396 	close(filedesc);
397 }
398 
399 ATF_TC_CLEANUP(fhopen_success, tc)
400 {
401 	cleanup();
402 }
403 
404 
405 ATF_TC_WITH_CLEANUP(fhopen_failure);
406 ATF_TC_HEAD(fhopen_failure, tc)
407 {
408 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
409 					"fhopen(2) call");
410 }
411 
412 ATF_TC_BODY(fhopen_failure, tc)
413 {
414 	const char *regex = "fhopen.*return,failure : Invalid argument";
415 	FILE *pipefd = setup(fds, auclass);
416 	/*
417 	 * Failure reason: NULL does not represent any file handle
418 	 * and O_CREAT is not allowed as the flag for fhopen(2)
419 	 */
420 	ATF_REQUIRE_EQ(-1, fhopen(NULL, O_CREAT));
421 	check_audit(fds, regex, pipefd);
422 }
423 
424 ATF_TC_CLEANUP(fhopen_failure, tc)
425 {
426 	cleanup();
427 }
428 
429 
430 ATF_TC_WITH_CLEANUP(fhstat_success);
431 ATF_TC_HEAD(fhstat_success, tc)
432 {
433 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
434 					"fstat(2) call");
435 }
436 
437 ATF_TC_BODY(fhstat_success, tc)
438 {
439 	pid = getpid();
440 	snprintf(extregex, sizeof(extregex), "fhstat.*%d.*return,success", pid);
441 
442 	/* File needs to exist to get a file-handle */
443 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
444 	/* Get the file handle to be passed to fhstat(2) */
445 	ATF_REQUIRE_EQ(0, getfh(path, &fht));
446 
447 	FILE *pipefd = setup(fds, auclass);
448 	ATF_REQUIRE_EQ(0, fhstat(&fht, &statbuff));
449 	check_audit(fds, extregex, pipefd);
450 	close(filedesc);
451 }
452 
453 ATF_TC_CLEANUP(fhstat_success, tc)
454 {
455 	cleanup();
456 }
457 
458 
459 ATF_TC_WITH_CLEANUP(fhstat_failure);
460 ATF_TC_HEAD(fhstat_failure, tc)
461 {
462 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
463 					"fhstat(2) call");
464 }
465 
466 ATF_TC_BODY(fhstat_failure, tc)
467 {
468 	const char *regex = "fhstat.*return,failure : Bad address";
469 	FILE *pipefd = setup(fds, auclass);
470 	/* Failure reason: NULL does not represent any file handle */
471 	ATF_REQUIRE_EQ(-1, fhstat(NULL, NULL));
472 	check_audit(fds, regex, pipefd);
473 }
474 
475 ATF_TC_CLEANUP(fhstat_failure, tc)
476 {
477 	cleanup();
478 }
479 
480 
481 ATF_TC_WITH_CLEANUP(fhstatfs_success);
482 ATF_TC_HEAD(fhstatfs_success, tc)
483 {
484 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
485 					"fstatfs(2) call");
486 }
487 
488 ATF_TC_BODY(fhstatfs_success, tc)
489 {
490 	pid = getpid();
491 	snprintf(extregex, sizeof(extregex), "fhstatfs.*%d.*success", pid);
492 
493 	/* File needs to exist to get a file-handle */
494 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
495 	/* Get the file handle to be passed to fhstatfs(2) */
496 	ATF_REQUIRE_EQ(0, getfh(path, &fht));
497 
498 	FILE *pipefd = setup(fds, auclass);
499 	ATF_REQUIRE_EQ(0, fhstatfs(&fht, &statfsbuff));
500 	check_audit(fds, extregex, pipefd);
501 	close(filedesc);
502 }
503 
504 ATF_TC_CLEANUP(fhstatfs_success, tc)
505 {
506 	cleanup();
507 }
508 
509 
510 ATF_TC_WITH_CLEANUP(fhstatfs_failure);
511 ATF_TC_HEAD(fhstatfs_failure, tc)
512 {
513 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
514 					"fhstatfs(2) call");
515 }
516 
517 ATF_TC_BODY(fhstatfs_failure, tc)
518 {
519 	const char *regex = "fhstatfs.*return,failure : Bad address";
520 	FILE *pipefd = setup(fds, auclass);
521 	/* Failure reason: NULL does not represent any file handle */
522 	ATF_REQUIRE_EQ(-1, fhstatfs(NULL, NULL));
523 	check_audit(fds, regex, pipefd);
524 }
525 
526 ATF_TC_CLEANUP(fhstatfs_failure, tc)
527 {
528 	cleanup();
529 }
530 
531 
532 ATF_TC_WITH_CLEANUP(access_success);
533 ATF_TC_HEAD(access_success, tc)
534 {
535 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
536 					"access(2) call");
537 }
538 
539 ATF_TC_BODY(access_success, tc)
540 {
541 	/* File needs to exist to call access(2) */
542 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
543 	FILE *pipefd = setup(fds, auclass);
544 	ATF_REQUIRE_EQ(0, access(path, F_OK));
545 	check_audit(fds, successreg, pipefd);
546 	close(filedesc);
547 }
548 
549 ATF_TC_CLEANUP(access_success, tc)
550 {
551 	cleanup();
552 }
553 
554 
555 ATF_TC_WITH_CLEANUP(access_failure);
556 ATF_TC_HEAD(access_failure, tc)
557 {
558 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
559 					"access(2) call");
560 }
561 
562 ATF_TC_BODY(access_failure, tc)
563 {
564 	FILE *pipefd = setup(fds, auclass);
565 	/* Failure reason: file does not exist */
566 	ATF_REQUIRE_EQ(-1, access(errpath, F_OK));
567 	check_audit(fds, failurereg, pipefd);
568 }
569 
570 ATF_TC_CLEANUP(access_failure, tc)
571 {
572 	cleanup();
573 }
574 
575 
576 ATF_TC_WITH_CLEANUP(eaccess_success);
577 ATF_TC_HEAD(eaccess_success, tc)
578 {
579 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
580 					"eaccess(2) call");
581 }
582 
583 ATF_TC_BODY(eaccess_success, tc)
584 {
585 	/* File needs to exist to call eaccess(2) */
586 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
587 	FILE *pipefd = setup(fds, auclass);
588 	ATF_REQUIRE_EQ(0, eaccess(path, F_OK));
589 	check_audit(fds, successreg, pipefd);
590 	close(filedesc);
591 }
592 
593 ATF_TC_CLEANUP(eaccess_success, tc)
594 {
595 	cleanup();
596 }
597 
598 
599 ATF_TC_WITH_CLEANUP(eaccess_failure);
600 ATF_TC_HEAD(eaccess_failure, tc)
601 {
602 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
603 					"eaccess(2) call");
604 }
605 
606 ATF_TC_BODY(eaccess_failure, tc)
607 {
608 	FILE *pipefd = setup(fds, auclass);
609 	/* Failure reason: file does not exist */
610 	ATF_REQUIRE_EQ(-1, eaccess(errpath, F_OK));
611 	check_audit(fds, failurereg, pipefd);
612 }
613 
614 ATF_TC_CLEANUP(eaccess_failure, tc)
615 {
616 	cleanup();
617 }
618 
619 
620 ATF_TC_WITH_CLEANUP(faccessat_success);
621 ATF_TC_HEAD(faccessat_success, tc)
622 {
623 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
624 					"faccessat(2) call");
625 }
626 
627 ATF_TC_BODY(faccessat_success, tc)
628 {
629 	/* File needs to exist to call faccessat(2) */
630 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
631 	FILE *pipefd = setup(fds, auclass);
632 	ATF_REQUIRE_EQ(0, faccessat(AT_FDCWD, path, F_OK, AT_EACCESS));
633 	check_audit(fds, successreg, pipefd);
634 	close(filedesc);
635 }
636 
637 ATF_TC_CLEANUP(faccessat_success, tc)
638 {
639 	cleanup();
640 }
641 
642 
643 ATF_TC_WITH_CLEANUP(faccessat_failure);
644 ATF_TC_HEAD(faccessat_failure, tc)
645 {
646 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
647 					"faccessat(2) call");
648 }
649 
650 ATF_TC_BODY(faccessat_failure, tc)
651 {
652 	FILE *pipefd = setup(fds, auclass);
653 	/* Failure reason: file does not exist */
654 	ATF_REQUIRE_EQ(-1, faccessat(AT_FDCWD, errpath, F_OK, AT_EACCESS));
655 	check_audit(fds, failurereg, pipefd);
656 }
657 
658 ATF_TC_CLEANUP(faccessat_failure, tc)
659 {
660 	cleanup();
661 }
662 
663 
664 ATF_TC_WITH_CLEANUP(pathconf_success);
665 ATF_TC_HEAD(pathconf_success, tc)
666 {
667 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
668 					"pathconf(2) call");
669 }
670 
671 ATF_TC_BODY(pathconf_success, tc)
672 {
673 	/* File needs to exist to call pathconf(2) */
674 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
675 	FILE *pipefd = setup(fds, auclass);
676 	/* Get the maximum number of bytes of filename */
677 	ATF_REQUIRE(pathconf(path, _PC_NAME_MAX) != -1);
678 	check_audit(fds, successreg, pipefd);
679 	close(filedesc);
680 }
681 
682 ATF_TC_CLEANUP(pathconf_success, tc)
683 {
684 	cleanup();
685 }
686 
687 
688 ATF_TC_WITH_CLEANUP(pathconf_failure);
689 ATF_TC_HEAD(pathconf_failure, tc)
690 {
691 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
692 					"pathconf(2) call");
693 }
694 
695 ATF_TC_BODY(pathconf_failure, tc)
696 {
697 	FILE *pipefd = setup(fds, auclass);
698 	/* Failure reason: file does not exist */
699 	ATF_REQUIRE_EQ(-1, pathconf(errpath, _PC_NAME_MAX));
700 	check_audit(fds, failurereg, pipefd);
701 }
702 
703 ATF_TC_CLEANUP(pathconf_failure, tc)
704 {
705 	cleanup();
706 }
707 
708 
709 ATF_TC_WITH_CLEANUP(lpathconf_success);
710 ATF_TC_HEAD(lpathconf_success, tc)
711 {
712 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
713 					"lpathconf(2) call");
714 }
715 
716 ATF_TC_BODY(lpathconf_success, tc)
717 {
718 	/* Symbolic link needs to exist to call lpathconf(2) */
719 	ATF_REQUIRE_EQ(0, symlink("symlink", path));
720 	FILE *pipefd = setup(fds, auclass);
721 	/* Get the maximum number of bytes of symlink's name */
722 	ATF_REQUIRE(lpathconf(path, _PC_SYMLINK_MAX) != -1);
723 	check_audit(fds, successreg, pipefd);
724 }
725 
726 ATF_TC_CLEANUP(lpathconf_success, tc)
727 {
728 	cleanup();
729 }
730 
731 
732 ATF_TC_WITH_CLEANUP(lpathconf_failure);
733 ATF_TC_HEAD(lpathconf_failure, tc)
734 {
735 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
736 					"lpathconf(2) call");
737 }
738 
739 ATF_TC_BODY(lpathconf_failure, tc)
740 {
741 	FILE *pipefd = setup(fds, auclass);
742 	/* Failure reason: symbolic link does not exist */
743 	ATF_REQUIRE_EQ(-1, lpathconf(errpath, _PC_SYMLINK_MAX));
744 	check_audit(fds, failurereg, pipefd);
745 }
746 
747 ATF_TC_CLEANUP(lpathconf_failure, tc)
748 {
749 	cleanup();
750 }
751 
752 
753 ATF_TC_WITH_CLEANUP(fpathconf_success);
754 ATF_TC_HEAD(fpathconf_success, tc)
755 {
756 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
757 					"fpathconf(2) call");
758 }
759 
760 ATF_TC_BODY(fpathconf_success, tc)
761 {
762 	pid = getpid();
763 	snprintf(extregex, sizeof(extregex), "fpathconf.*%d.*success", pid);
764 
765 	/* File needs to exist to call fpathconf(2) */
766 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
767 	FILE *pipefd = setup(fds, auclass);
768 	/* Get the maximum number of bytes of filename */
769 	ATF_REQUIRE(fpathconf(filedesc, _PC_NAME_MAX) != -1);
770 	check_audit(fds, extregex, pipefd);
771 	close(filedesc);
772 }
773 
774 ATF_TC_CLEANUP(fpathconf_success, tc)
775 {
776 	cleanup();
777 }
778 
779 
780 ATF_TC_WITH_CLEANUP(fpathconf_failure);
781 ATF_TC_HEAD(fpathconf_failure, tc)
782 {
783 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
784 					"fpathconf(2) call");
785 }
786 
787 ATF_TC_BODY(fpathconf_failure, tc)
788 {
789 	FILE *pipefd = setup(fds, auclass);
790 	const char *regex = "fpathconf.*return,failure : Bad file descriptor";
791 	/* Failure reason: Bad file descriptor */
792 	ATF_REQUIRE_EQ(-1, fpathconf(-1, _PC_NAME_MAX));
793 	check_audit(fds, regex, pipefd);
794 }
795 
796 ATF_TC_CLEANUP(fpathconf_failure, tc)
797 {
798 	cleanup();
799 }
800 
801 
802 ATF_TP_ADD_TCS(tp)
803 {
804 	ATF_TP_ADD_TC(tp, stat_success);
805 	ATF_TP_ADD_TC(tp, stat_failure);
806 	ATF_TP_ADD_TC(tp, lstat_success);
807 	ATF_TP_ADD_TC(tp, lstat_failure);
808 	ATF_TP_ADD_TC(tp, fstat_success);
809 	ATF_TP_ADD_TC(tp, fstat_failure);
810 	ATF_TP_ADD_TC(tp, fstatat_success);
811 	ATF_TP_ADD_TC(tp, fstatat_failure);
812 
813 	ATF_TP_ADD_TC(tp, statfs_success);
814 	ATF_TP_ADD_TC(tp, statfs_failure);
815 	ATF_TP_ADD_TC(tp, fstatfs_success);
816 	ATF_TP_ADD_TC(tp, fstatfs_failure);
817 
818 	ATF_TP_ADD_TC(tp, getfsstat_success);
819 	ATF_TP_ADD_TC(tp, getfsstat_failure);
820 
821 	ATF_TP_ADD_TC(tp, fhopen_success);
822 	ATF_TP_ADD_TC(tp, fhopen_failure);
823 	ATF_TP_ADD_TC(tp, fhstat_success);
824 	ATF_TP_ADD_TC(tp, fhstat_failure);
825 	ATF_TP_ADD_TC(tp, fhstatfs_success);
826 	ATF_TP_ADD_TC(tp, fhstatfs_failure);
827 
828 	ATF_TP_ADD_TC(tp, access_success);
829 	ATF_TP_ADD_TC(tp, access_failure);
830 	ATF_TP_ADD_TC(tp, eaccess_success);
831 	ATF_TP_ADD_TC(tp, eaccess_failure);
832 	ATF_TP_ADD_TC(tp, faccessat_success);
833 	ATF_TP_ADD_TC(tp, faccessat_failure);
834 
835 	ATF_TP_ADD_TC(tp, pathconf_success);
836 	ATF_TP_ADD_TC(tp, pathconf_failure);
837 	ATF_TP_ADD_TC(tp, lpathconf_success);
838 	ATF_TP_ADD_TC(tp, lpathconf_failure);
839 	ATF_TP_ADD_TC(tp, fpathconf_success);
840 	ATF_TP_ADD_TC(tp, fpathconf_failure);
841 
842 	return (atf_no_error());
843 }
844