xref: /freebsd/tests/sys/audit/file-attribute-access.c (revision f86d65170b22eddddaf4693d4dfeb3e99e3a2023)
1*f86d6517SAlan Somers /*-
2*f86d6517SAlan Somers  * Copyright (c) 2018 Aniket Pandey
3*f86d6517SAlan Somers  *
4*f86d6517SAlan Somers  * Redistribution and use in source and binary forms, with or without
5*f86d6517SAlan Somers  * modification, are permitted provided that the following conditions
6*f86d6517SAlan Somers  * are met:
7*f86d6517SAlan Somers  * 1. Redistributions of source code must retain the above copyright
8*f86d6517SAlan Somers  *    notice, this list of conditions and the following disclaimer.
9*f86d6517SAlan Somers  * 2. Redistributions in binary form must reproduce the above copyright
10*f86d6517SAlan Somers  *    notice, this list of conditions and the following disclaimer in the
11*f86d6517SAlan Somers  *    documentation and/or other materials provided with the distribution.
12*f86d6517SAlan Somers  *
13*f86d6517SAlan Somers  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14*f86d6517SAlan Somers  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15*f86d6517SAlan Somers  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16*f86d6517SAlan Somers  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17*f86d6517SAlan Somers  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18*f86d6517SAlan Somers  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19*f86d6517SAlan Somers  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
20*f86d6517SAlan Somers  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*f86d6517SAlan Somers  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*f86d6517SAlan Somers  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*f86d6517SAlan Somers  * SUCH DAMAGE.
24*f86d6517SAlan Somers  *
25*f86d6517SAlan Somers  * $FreeBSD$
26*f86d6517SAlan Somers  */
27*f86d6517SAlan Somers 
28*f86d6517SAlan Somers #include <sys/stat.h>
29*f86d6517SAlan Somers #include <sys/syscall.h>
30*f86d6517SAlan Somers 
31*f86d6517SAlan Somers #include <atf-c.h>
32*f86d6517SAlan Somers #include <fcntl.h>
33*f86d6517SAlan Somers #include <unistd.h>
34*f86d6517SAlan Somers 
35*f86d6517SAlan Somers #include "utils.h"
36*f86d6517SAlan Somers 
37*f86d6517SAlan Somers static struct pollfd fds[1];
38*f86d6517SAlan Somers static mode_t mode = 0777;
39*f86d6517SAlan Somers static char extregex[80];
40*f86d6517SAlan Somers static struct stat statbuff;
41*f86d6517SAlan Somers static const char *auclass = "fa";
42*f86d6517SAlan Somers static const char *path = "fileforaudit";
43*f86d6517SAlan Somers static const char *errpath = "dirdoesnotexist/fileforaudit";
44*f86d6517SAlan Somers static const char *successreg = "fileforaudit.*return,success";
45*f86d6517SAlan Somers static const char *failurereg = "fileforaudit.*return,failure";
46*f86d6517SAlan Somers 
47*f86d6517SAlan Somers 
48*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(stat_success);
49*f86d6517SAlan Somers ATF_TC_HEAD(stat_success, tc)
50*f86d6517SAlan Somers {
51*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
52*f86d6517SAlan Somers 					"stat(2) call");
53*f86d6517SAlan Somers }
54*f86d6517SAlan Somers 
55*f86d6517SAlan Somers ATF_TC_BODY(stat_success, tc)
56*f86d6517SAlan Somers {
57*f86d6517SAlan Somers 	/* File needs to exist to call stat(2) */
58*f86d6517SAlan Somers 	ATF_REQUIRE(open(path, O_CREAT, mode) != -1);
59*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
60*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(0, stat(path, &statbuff));
61*f86d6517SAlan Somers 	check_audit(fds, successreg, pipefd);
62*f86d6517SAlan Somers }
63*f86d6517SAlan Somers 
64*f86d6517SAlan Somers ATF_TC_CLEANUP(stat_success, tc)
65*f86d6517SAlan Somers {
66*f86d6517SAlan Somers 	cleanup();
67*f86d6517SAlan Somers }
68*f86d6517SAlan Somers 
69*f86d6517SAlan Somers 
70*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(stat_failure);
71*f86d6517SAlan Somers ATF_TC_HEAD(stat_failure, tc)
72*f86d6517SAlan Somers {
73*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
74*f86d6517SAlan Somers 					"stat(2) call");
75*f86d6517SAlan Somers }
76*f86d6517SAlan Somers 
77*f86d6517SAlan Somers ATF_TC_BODY(stat_failure, tc)
78*f86d6517SAlan Somers {
79*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
80*f86d6517SAlan Somers 	/* Failure reason: file does not exist */
81*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(-1, stat(errpath, &statbuff));
82*f86d6517SAlan Somers 	check_audit(fds, failurereg, pipefd);
83*f86d6517SAlan Somers }
84*f86d6517SAlan Somers 
85*f86d6517SAlan Somers ATF_TC_CLEANUP(stat_failure, tc)
86*f86d6517SAlan Somers {
87*f86d6517SAlan Somers 	cleanup();
88*f86d6517SAlan Somers }
89*f86d6517SAlan Somers 
90*f86d6517SAlan Somers 
91*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(lstat_success);
92*f86d6517SAlan Somers ATF_TC_HEAD(lstat_success, tc)
93*f86d6517SAlan Somers {
94*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
95*f86d6517SAlan Somers 					"lstat(2) call");
96*f86d6517SAlan Somers }
97*f86d6517SAlan Somers 
98*f86d6517SAlan Somers ATF_TC_BODY(lstat_success, tc)
99*f86d6517SAlan Somers {
100*f86d6517SAlan Somers 	/* Symbolic link needs to exist to call lstat(2) */
101*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(0, symlink("symlink", path));
102*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
103*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(0, lstat(path, &statbuff));
104*f86d6517SAlan Somers 	check_audit(fds, successreg, pipefd);
105*f86d6517SAlan Somers }
106*f86d6517SAlan Somers 
107*f86d6517SAlan Somers ATF_TC_CLEANUP(lstat_success, tc)
108*f86d6517SAlan Somers {
109*f86d6517SAlan Somers 	cleanup();
110*f86d6517SAlan Somers }
111*f86d6517SAlan Somers 
112*f86d6517SAlan Somers 
113*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(lstat_failure);
114*f86d6517SAlan Somers ATF_TC_HEAD(lstat_failure, tc)
115*f86d6517SAlan Somers {
116*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
117*f86d6517SAlan Somers 					"lstat(2) call");
118*f86d6517SAlan Somers }
119*f86d6517SAlan Somers 
120*f86d6517SAlan Somers ATF_TC_BODY(lstat_failure, tc)
121*f86d6517SAlan Somers {
122*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
123*f86d6517SAlan Somers 	/* Failure reason: symbolic link does not exist */
124*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(-1, lstat(errpath, &statbuff));
125*f86d6517SAlan Somers 	check_audit(fds, failurereg, pipefd);
126*f86d6517SAlan Somers }
127*f86d6517SAlan Somers 
128*f86d6517SAlan Somers ATF_TC_CLEANUP(lstat_failure, tc)
129*f86d6517SAlan Somers {
130*f86d6517SAlan Somers 	cleanup();
131*f86d6517SAlan Somers }
132*f86d6517SAlan Somers 
133*f86d6517SAlan Somers 
134*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(fstat_success);
135*f86d6517SAlan Somers ATF_TC_HEAD(fstat_success, tc)
136*f86d6517SAlan Somers {
137*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
138*f86d6517SAlan Somers 					"fstat(2) call");
139*f86d6517SAlan Somers }
140*f86d6517SAlan Somers 
141*f86d6517SAlan Somers ATF_TC_BODY(fstat_success, tc)
142*f86d6517SAlan Somers {
143*f86d6517SAlan Somers 	int filedesc;
144*f86d6517SAlan Somers 	/* File needs to exist to call fstat(2) */
145*f86d6517SAlan Somers 	ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1);
146*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
147*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(0, fstat(filedesc, &statbuff));
148*f86d6517SAlan Somers 
149*f86d6517SAlan Somers 	snprintf(extregex, sizeof(extregex),
150*f86d6517SAlan Somers 		"fstat.*%jd.*return,success", (intmax_t)statbuff.st_ino);
151*f86d6517SAlan Somers 	check_audit(fds, extregex, pipefd);
152*f86d6517SAlan Somers }
153*f86d6517SAlan Somers 
154*f86d6517SAlan Somers ATF_TC_CLEANUP(fstat_success, tc)
155*f86d6517SAlan Somers {
156*f86d6517SAlan Somers 	cleanup();
157*f86d6517SAlan Somers }
158*f86d6517SAlan Somers 
159*f86d6517SAlan Somers 
160*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(fstat_failure);
161*f86d6517SAlan Somers ATF_TC_HEAD(fstat_failure, tc)
162*f86d6517SAlan Somers {
163*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
164*f86d6517SAlan Somers 					"fstat(2) call");
165*f86d6517SAlan Somers }
166*f86d6517SAlan Somers 
167*f86d6517SAlan Somers ATF_TC_BODY(fstat_failure, tc)
168*f86d6517SAlan Somers {
169*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
170*f86d6517SAlan Somers 	const char *regex = "fstat.*return,failure : Bad file descriptor";
171*f86d6517SAlan Somers 	/* Failure reason: bad file descriptor */
172*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(-1, fstat(-1, &statbuff));
173*f86d6517SAlan Somers 	check_audit(fds, regex, pipefd);
174*f86d6517SAlan Somers }
175*f86d6517SAlan Somers 
176*f86d6517SAlan Somers ATF_TC_CLEANUP(fstat_failure, tc)
177*f86d6517SAlan Somers {
178*f86d6517SAlan Somers 	cleanup();
179*f86d6517SAlan Somers }
180*f86d6517SAlan Somers 
181*f86d6517SAlan Somers 
182*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(fstatat_success);
183*f86d6517SAlan Somers ATF_TC_HEAD(fstatat_success, tc)
184*f86d6517SAlan Somers {
185*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
186*f86d6517SAlan Somers 					"fstatat(2) call");
187*f86d6517SAlan Somers }
188*f86d6517SAlan Somers 
189*f86d6517SAlan Somers ATF_TC_BODY(fstatat_success, tc)
190*f86d6517SAlan Somers {
191*f86d6517SAlan Somers 	/* File or Symbolic link needs to exist to call lstat(2) */
192*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(0, symlink("symlink", path));
193*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
194*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(0, fstatat(AT_FDCWD, path, &statbuff,
195*f86d6517SAlan Somers 		AT_SYMLINK_NOFOLLOW));
196*f86d6517SAlan Somers 	check_audit(fds, successreg, pipefd);
197*f86d6517SAlan Somers }
198*f86d6517SAlan Somers 
199*f86d6517SAlan Somers ATF_TC_CLEANUP(fstatat_success, tc)
200*f86d6517SAlan Somers {
201*f86d6517SAlan Somers 	cleanup();
202*f86d6517SAlan Somers }
203*f86d6517SAlan Somers 
204*f86d6517SAlan Somers 
205*f86d6517SAlan Somers ATF_TC_WITH_CLEANUP(fstatat_failure);
206*f86d6517SAlan Somers ATF_TC_HEAD(fstatat_failure, tc)
207*f86d6517SAlan Somers {
208*f86d6517SAlan Somers 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
209*f86d6517SAlan Somers 					"fstatat(2) call");
210*f86d6517SAlan Somers }
211*f86d6517SAlan Somers 
212*f86d6517SAlan Somers ATF_TC_BODY(fstatat_failure, tc)
213*f86d6517SAlan Somers {
214*f86d6517SAlan Somers 	FILE *pipefd = setup(fds, auclass);
215*f86d6517SAlan Somers 	/* Failure reason: symbolic link does not exist */
216*f86d6517SAlan Somers 	ATF_REQUIRE_EQ(-1, fstatat(AT_FDCWD, path, &statbuff,
217*f86d6517SAlan Somers 		AT_SYMLINK_NOFOLLOW));
218*f86d6517SAlan Somers 	check_audit(fds, failurereg, pipefd);
219*f86d6517SAlan Somers }
220*f86d6517SAlan Somers 
221*f86d6517SAlan Somers ATF_TC_CLEANUP(fstatat_failure, tc)
222*f86d6517SAlan Somers {
223*f86d6517SAlan Somers 	cleanup();
224*f86d6517SAlan Somers }
225*f86d6517SAlan Somers 
226*f86d6517SAlan Somers 
227*f86d6517SAlan Somers ATF_TP_ADD_TCS(tp)
228*f86d6517SAlan Somers {
229*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, stat_success);
230*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, stat_failure);
231*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, lstat_success);
232*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, lstat_failure);
233*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, fstat_success);
234*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, fstat_failure);
235*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, fstatat_success);
236*f86d6517SAlan Somers 	ATF_TP_ADD_TC(tp, fstatat_failure);
237*f86d6517SAlan Somers 
238*f86d6517SAlan Somers 	return (atf_no_error());
239*f86d6517SAlan Somers }
240