]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/audit/file-attribute-access.c
audit(4): add tests for stat(2) and friends
[FreeBSD/FreeBSD.git] / tests / sys / audit / file-attribute-access.c
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/stat.h>
29 #include <sys/syscall.h>
30
31 #include <atf-c.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34
35 #include "utils.h"
36
37 static struct pollfd fds[1];
38 static mode_t mode = 0777;
39 static char extregex[80];
40 static struct stat statbuff;
41 static const char *auclass = "fa";
42 static const char *path = "fileforaudit";
43 static const char *errpath = "dirdoesnotexist/fileforaudit";
44 static const char *successreg = "fileforaudit.*return,success";
45 static const char *failurereg = "fileforaudit.*return,failure";
46
47
48 ATF_TC_WITH_CLEANUP(stat_success);
49 ATF_TC_HEAD(stat_success, tc)
50 {
51         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
52                                         "stat(2) call");
53 }
54
55 ATF_TC_BODY(stat_success, tc)
56 {
57         /* File needs to exist to call stat(2) */
58         ATF_REQUIRE(open(path, O_CREAT, mode) != -1);
59         FILE *pipefd = setup(fds, auclass);
60         ATF_REQUIRE_EQ(0, stat(path, &statbuff));
61         check_audit(fds, successreg, pipefd);
62 }
63
64 ATF_TC_CLEANUP(stat_success, tc)
65 {
66         cleanup();
67 }
68
69
70 ATF_TC_WITH_CLEANUP(stat_failure);
71 ATF_TC_HEAD(stat_failure, tc)
72 {
73         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
74                                         "stat(2) call");
75 }
76
77 ATF_TC_BODY(stat_failure, tc)
78 {
79         FILE *pipefd = setup(fds, auclass);
80         /* Failure reason: file does not exist */
81         ATF_REQUIRE_EQ(-1, stat(errpath, &statbuff));
82         check_audit(fds, failurereg, pipefd);
83 }
84
85 ATF_TC_CLEANUP(stat_failure, tc)
86 {
87         cleanup();
88 }
89
90
91 ATF_TC_WITH_CLEANUP(lstat_success);
92 ATF_TC_HEAD(lstat_success, tc)
93 {
94         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
95                                         "lstat(2) call");
96 }
97
98 ATF_TC_BODY(lstat_success, tc)
99 {
100         /* Symbolic link needs to exist to call lstat(2) */
101         ATF_REQUIRE_EQ(0, symlink("symlink", path));
102         FILE *pipefd = setup(fds, auclass);
103         ATF_REQUIRE_EQ(0, lstat(path, &statbuff));
104         check_audit(fds, successreg, pipefd);
105 }
106
107 ATF_TC_CLEANUP(lstat_success, tc)
108 {
109         cleanup();
110 }
111
112
113 ATF_TC_WITH_CLEANUP(lstat_failure);
114 ATF_TC_HEAD(lstat_failure, tc)
115 {
116         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
117                                         "lstat(2) call");
118 }
119
120 ATF_TC_BODY(lstat_failure, tc)
121 {
122         FILE *pipefd = setup(fds, auclass);
123         /* Failure reason: symbolic link does not exist */
124         ATF_REQUIRE_EQ(-1, lstat(errpath, &statbuff));
125         check_audit(fds, failurereg, pipefd);
126 }
127
128 ATF_TC_CLEANUP(lstat_failure, tc)
129 {
130         cleanup();
131 }
132
133
134 ATF_TC_WITH_CLEANUP(fstat_success);
135 ATF_TC_HEAD(fstat_success, tc)
136 {
137         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
138                                         "fstat(2) call");
139 }
140
141 ATF_TC_BODY(fstat_success, tc)
142 {
143         int filedesc;
144         /* File needs to exist to call fstat(2) */
145         ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1);
146         FILE *pipefd = setup(fds, auclass);
147         ATF_REQUIRE_EQ(0, fstat(filedesc, &statbuff));
148
149         snprintf(extregex, sizeof(extregex),
150                 "fstat.*%jd.*return,success", (intmax_t)statbuff.st_ino);
151         check_audit(fds, extregex, pipefd);
152 }
153
154 ATF_TC_CLEANUP(fstat_success, tc)
155 {
156         cleanup();
157 }
158
159
160 ATF_TC_WITH_CLEANUP(fstat_failure);
161 ATF_TC_HEAD(fstat_failure, tc)
162 {
163         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
164                                         "fstat(2) call");
165 }
166
167 ATF_TC_BODY(fstat_failure, tc)
168 {
169         FILE *pipefd = setup(fds, auclass);
170         const char *regex = "fstat.*return,failure : Bad file descriptor";
171         /* Failure reason: bad file descriptor */
172         ATF_REQUIRE_EQ(-1, fstat(-1, &statbuff));
173         check_audit(fds, regex, pipefd);
174 }
175
176 ATF_TC_CLEANUP(fstat_failure, tc)
177 {
178         cleanup();
179 }
180
181
182 ATF_TC_WITH_CLEANUP(fstatat_success);
183 ATF_TC_HEAD(fstatat_success, tc)
184 {
185         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
186                                         "fstatat(2) call");
187 }
188
189 ATF_TC_BODY(fstatat_success, tc)
190 {
191         /* File or Symbolic link needs to exist to call lstat(2) */
192         ATF_REQUIRE_EQ(0, symlink("symlink", path));
193         FILE *pipefd = setup(fds, auclass);
194         ATF_REQUIRE_EQ(0, fstatat(AT_FDCWD, path, &statbuff,
195                 AT_SYMLINK_NOFOLLOW));
196         check_audit(fds, successreg, pipefd);
197 }
198
199 ATF_TC_CLEANUP(fstatat_success, tc)
200 {
201         cleanup();
202 }
203
204
205 ATF_TC_WITH_CLEANUP(fstatat_failure);
206 ATF_TC_HEAD(fstatat_failure, tc)
207 {
208         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
209                                         "fstatat(2) call");
210 }
211
212 ATF_TC_BODY(fstatat_failure, tc)
213 {
214         FILE *pipefd = setup(fds, auclass);
215         /* Failure reason: symbolic link does not exist */
216         ATF_REQUIRE_EQ(-1, fstatat(AT_FDCWD, path, &statbuff,
217                 AT_SYMLINK_NOFOLLOW));
218         check_audit(fds, failurereg, pipefd);
219 }
220
221 ATF_TC_CLEANUP(fstatat_failure, tc)
222 {
223         cleanup();
224 }
225
226
227 ATF_TP_ADD_TCS(tp)
228 {
229         ATF_TP_ADD_TC(tp, stat_success);
230         ATF_TP_ADD_TC(tp, stat_failure);
231         ATF_TP_ADD_TC(tp, lstat_success);
232         ATF_TP_ADD_TC(tp, lstat_failure);
233         ATF_TP_ADD_TC(tp, fstat_success);
234         ATF_TP_ADD_TC(tp, fstat_failure);
235         ATF_TP_ADD_TC(tp, fstatat_success);
236         ATF_TP_ADD_TC(tp, fstatat_failure);
237
238         return (atf_no_error());
239 }