2 * Copyright (c) 2018 Aniket Pandey
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/param.h>
29 #include <sys/ucred.h>
30 #include <sys/mount.h>
32 #include <sys/syscall.h>
40 static struct pollfd fds[1];
41 static mode_t mode = 0777;
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";
55 ATF_TC_WITH_CLEANUP(stat_success);
56 ATF_TC_HEAD(stat_success, tc)
58 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
62 ATF_TC_BODY(stat_success, tc)
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);
72 ATF_TC_CLEANUP(stat_success, tc)
78 ATF_TC_WITH_CLEANUP(stat_failure);
79 ATF_TC_HEAD(stat_failure, tc)
81 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
85 ATF_TC_BODY(stat_failure, tc)
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);
93 ATF_TC_CLEANUP(stat_failure, tc)
99 ATF_TC_WITH_CLEANUP(lstat_success);
100 ATF_TC_HEAD(lstat_success, tc)
102 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
106 ATF_TC_BODY(lstat_success, tc)
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);
115 ATF_TC_CLEANUP(lstat_success, tc)
121 ATF_TC_WITH_CLEANUP(lstat_failure);
122 ATF_TC_HEAD(lstat_failure, tc)
124 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
128 ATF_TC_BODY(lstat_failure, tc)
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);
136 ATF_TC_CLEANUP(lstat_failure, tc)
142 ATF_TC_WITH_CLEANUP(fstat_success);
143 ATF_TC_HEAD(fstat_success, tc)
145 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
149 ATF_TC_BODY(fstat_success, tc)
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));
156 snprintf(extregex, sizeof(extregex),
157 "fstat.*%jd.*return,success", (intmax_t)statbuff.st_ino);
158 check_audit(fds, extregex, pipefd);
162 ATF_TC_CLEANUP(fstat_success, tc)
168 ATF_TC_WITH_CLEANUP(fstat_failure);
169 ATF_TC_HEAD(fstat_failure, tc)
171 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
175 ATF_TC_BODY(fstat_failure, tc)
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);
184 ATF_TC_CLEANUP(fstat_failure, tc)
190 ATF_TC_WITH_CLEANUP(fstatat_success);
191 ATF_TC_HEAD(fstatat_success, tc)
193 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
197 ATF_TC_BODY(fstatat_success, tc)
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);
207 ATF_TC_CLEANUP(fstatat_success, tc)
213 ATF_TC_WITH_CLEANUP(fstatat_failure);
214 ATF_TC_HEAD(fstatat_failure, tc)
216 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
220 ATF_TC_BODY(fstatat_failure, tc)
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);
229 ATF_TC_CLEANUP(fstatat_failure, tc)
235 ATF_TC_WITH_CLEANUP(statfs_success);
236 ATF_TC_HEAD(statfs_success, tc)
238 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
242 ATF_TC_BODY(statfs_success, tc)
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);
252 ATF_TC_CLEANUP(statfs_success, tc)
258 ATF_TC_WITH_CLEANUP(statfs_failure);
259 ATF_TC_HEAD(statfs_failure, tc)
261 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
265 ATF_TC_BODY(statfs_failure, tc)
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);
273 ATF_TC_CLEANUP(statfs_failure, tc)
279 ATF_TC_WITH_CLEANUP(fstatfs_success);
280 ATF_TC_HEAD(fstatfs_success, tc)
282 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
286 ATF_TC_BODY(fstatfs_success, tc)
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));
295 snprintf(extregex, sizeof(extregex), "fstatfs.*%jd.*return,success",
296 (intmax_t)statbuff.st_ino);
297 check_audit(fds, extregex, pipefd);
301 ATF_TC_CLEANUP(fstatfs_success, tc)
307 ATF_TC_WITH_CLEANUP(fstatfs_failure);
308 ATF_TC_HEAD(fstatfs_failure, tc)
310 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
314 ATF_TC_BODY(fstatfs_failure, tc)
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);
323 ATF_TC_CLEANUP(fstatfs_failure, tc)
329 ATF_TC_WITH_CLEANUP(getfsstat_success);
330 ATF_TC_HEAD(getfsstat_success, tc)
332 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
333 "getfsstat(2) call");
336 ATF_TC_BODY(getfsstat_success, tc)
339 snprintf(extregex, sizeof(extregex), "getfsstat.*%d.*success", pid);
341 FILE *pipefd = setup(fds, auclass);
342 ATF_REQUIRE(getfsstat(NULL, 0, MNT_NOWAIT) != -1);
343 check_audit(fds, extregex, pipefd);
346 ATF_TC_CLEANUP(getfsstat_success, tc)
352 ATF_TC_WITH_CLEANUP(getfsstat_failure);
353 ATF_TC_HEAD(getfsstat_failure, tc)
355 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
356 "getfsstat(2) call");
359 ATF_TC_BODY(getfsstat_failure, tc)
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);
368 ATF_TC_CLEANUP(getfsstat_failure, tc)
374 ATF_TC_WITH_CLEANUP(fhopen_success);
375 ATF_TC_HEAD(fhopen_success, tc)
377 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
381 ATF_TC_BODY(fhopen_success, tc)
384 snprintf(extregex, sizeof(extregex), "fhopen.*%d.*return,success", pid);
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));
391 FILE *pipefd = setup(fds, auclass);
392 ATF_REQUIRE((fhdesc = fhopen(&fht, O_RDWR)) != -1);
393 check_audit(fds, extregex, pipefd);
399 ATF_TC_CLEANUP(fhopen_success, tc)
405 ATF_TC_WITH_CLEANUP(fhopen_failure);
406 ATF_TC_HEAD(fhopen_failure, tc)
408 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
412 ATF_TC_BODY(fhopen_failure, tc)
414 const char *regex = "fhopen.*return,failure : Invalid argument";
415 FILE *pipefd = setup(fds, auclass);
417 * Failure reason: NULL does not represent any file handle
418 * and O_CREAT is not allowed as the flag for fhopen(2)
420 ATF_REQUIRE_EQ(-1, fhopen(NULL, O_CREAT));
421 check_audit(fds, regex, pipefd);
424 ATF_TC_CLEANUP(fhopen_failure, tc)
430 ATF_TC_WITH_CLEANUP(fhstat_success);
431 ATF_TC_HEAD(fhstat_success, tc)
433 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
437 ATF_TC_BODY(fhstat_success, tc)
440 snprintf(extregex, sizeof(extregex), "fhstat.*%d.*return,success", pid);
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));
447 FILE *pipefd = setup(fds, auclass);
448 ATF_REQUIRE_EQ(0, fhstat(&fht, &statbuff));
449 check_audit(fds, extregex, pipefd);
453 ATF_TC_CLEANUP(fhstat_success, tc)
459 ATF_TC_WITH_CLEANUP(fhstat_failure);
460 ATF_TC_HEAD(fhstat_failure, tc)
462 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
466 ATF_TC_BODY(fhstat_failure, tc)
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);
475 ATF_TC_CLEANUP(fhstat_failure, tc)
481 ATF_TC_WITH_CLEANUP(fhstatfs_success);
482 ATF_TC_HEAD(fhstatfs_success, tc)
484 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
488 ATF_TC_BODY(fhstatfs_success, tc)
491 snprintf(extregex, sizeof(extregex), "fhstatfs.*%d.*success", pid);
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));
498 FILE *pipefd = setup(fds, auclass);
499 ATF_REQUIRE_EQ(0, fhstatfs(&fht, &statfsbuff));
500 check_audit(fds, extregex, pipefd);
504 ATF_TC_CLEANUP(fhstatfs_success, tc)
510 ATF_TC_WITH_CLEANUP(fhstatfs_failure);
511 ATF_TC_HEAD(fhstatfs_failure, tc)
513 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
517 ATF_TC_BODY(fhstatfs_failure, tc)
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);
526 ATF_TC_CLEANUP(fhstatfs_failure, tc)
532 ATF_TC_WITH_CLEANUP(access_success);
533 ATF_TC_HEAD(access_success, tc)
535 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
539 ATF_TC_BODY(access_success, tc)
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);
549 ATF_TC_CLEANUP(access_success, tc)
555 ATF_TC_WITH_CLEANUP(access_failure);
556 ATF_TC_HEAD(access_failure, tc)
558 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
562 ATF_TC_BODY(access_failure, tc)
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);
570 ATF_TC_CLEANUP(access_failure, tc)
576 ATF_TC_WITH_CLEANUP(eaccess_success);
577 ATF_TC_HEAD(eaccess_success, tc)
579 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
583 ATF_TC_BODY(eaccess_success, tc)
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);
593 ATF_TC_CLEANUP(eaccess_success, tc)
599 ATF_TC_WITH_CLEANUP(eaccess_failure);
600 ATF_TC_HEAD(eaccess_failure, tc)
602 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
606 ATF_TC_BODY(eaccess_failure, tc)
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);
614 ATF_TC_CLEANUP(eaccess_failure, tc)
620 ATF_TC_WITH_CLEANUP(faccessat_success);
621 ATF_TC_HEAD(faccessat_success, tc)
623 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
624 "faccessat(2) call");
627 ATF_TC_BODY(faccessat_success, tc)
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);
637 ATF_TC_CLEANUP(faccessat_success, tc)
643 ATF_TC_WITH_CLEANUP(faccessat_failure);
644 ATF_TC_HEAD(faccessat_failure, tc)
646 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
647 "faccessat(2) call");
650 ATF_TC_BODY(faccessat_failure, tc)
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);
658 ATF_TC_CLEANUP(faccessat_failure, tc)
666 ATF_TP_ADD_TC(tp, stat_success);
667 ATF_TP_ADD_TC(tp, stat_failure);
668 ATF_TP_ADD_TC(tp, lstat_success);
669 ATF_TP_ADD_TC(tp, lstat_failure);
670 ATF_TP_ADD_TC(tp, fstat_success);
671 ATF_TP_ADD_TC(tp, fstat_failure);
672 ATF_TP_ADD_TC(tp, fstatat_success);
673 ATF_TP_ADD_TC(tp, fstatat_failure);
675 ATF_TP_ADD_TC(tp, statfs_success);
676 ATF_TP_ADD_TC(tp, statfs_failure);
677 ATF_TP_ADD_TC(tp, fstatfs_success);
678 ATF_TP_ADD_TC(tp, fstatfs_failure);
680 ATF_TP_ADD_TC(tp, getfsstat_success);
681 ATF_TP_ADD_TC(tp, getfsstat_failure);
683 ATF_TP_ADD_TC(tp, fhopen_success);
684 ATF_TP_ADD_TC(tp, fhopen_failure);
685 ATF_TP_ADD_TC(tp, fhstat_success);
686 ATF_TP_ADD_TC(tp, fhstat_failure);
687 ATF_TP_ADD_TC(tp, fhstatfs_success);
688 ATF_TP_ADD_TC(tp, fhstatfs_failure);
690 ATF_TP_ADD_TC(tp, access_success);
691 ATF_TP_ADD_TC(tp, access_failure);
692 ATF_TP_ADD_TC(tp, eaccess_success);
693 ATF_TP_ADD_TC(tp, eaccess_failure);
694 ATF_TP_ADD_TC(tp, faccessat_success);
695 ATF_TP_ADD_TC(tp, faccessat_failure);
697 return (atf_no_error());