xref: /freebsd/tests/sys/audit/file-create.c (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1 /*-
2  * Copyright 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 
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 
29 #include <atf-c.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 
34 #include "utils.h"
35 
36 static struct pollfd fds[1];
37 static mode_t mode = 0777;
38 static int filedesc;
39 static dev_t dev =  0;
40 static const char *auclass = "fc";
41 static const char *path = "fileforaudit";
42 static const char *successreg = "fileforaudit.*return,success";
43 static const char *failurereg = "fileforaudit.*return,failure";
44 
45 
46 ATF_TC_WITH_CLEANUP(mkdir_success);
47 ATF_TC_HEAD(mkdir_success, tc)
48 {
49 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
50 					"mkdir(2) call");
51 }
52 
53 ATF_TC_BODY(mkdir_success, tc)
54 {
55 	FILE *pipefd = setup(fds, auclass);
56 	ATF_REQUIRE_EQ(0, mkdir(path, mode));
57 	check_audit(fds, successreg, pipefd);
58 }
59 
60 ATF_TC_CLEANUP(mkdir_success, tc)
61 {
62 	cleanup();
63 }
64 
65 
66 ATF_TC_WITH_CLEANUP(mkdir_failure);
67 ATF_TC_HEAD(mkdir_failure, tc)
68 {
69 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
70 					"mkdir(2) call");
71 }
72 
73 ATF_TC_BODY(mkdir_failure, tc)
74 {
75 	ATF_REQUIRE_EQ(0, mkdir(path, mode));
76 	FILE *pipefd = setup(fds, auclass);
77 	/* Failure reason: directory already exists */
78 	ATF_REQUIRE_EQ(-1, mkdir(path, mode));
79 	check_audit(fds, failurereg, pipefd);
80 }
81 
82 ATF_TC_CLEANUP(mkdir_failure, tc)
83 {
84 	cleanup();
85 }
86 
87 
88 ATF_TC_WITH_CLEANUP(mkdirat_success);
89 ATF_TC_HEAD(mkdirat_success, tc)
90 {
91 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
92 					"mkdirat(2) call");
93 }
94 
95 ATF_TC_BODY(mkdirat_success, tc)
96 {
97 	FILE *pipefd = setup(fds, auclass);
98 	ATF_REQUIRE_EQ(0, mkdirat(AT_FDCWD, path, mode));
99 	check_audit(fds, successreg, pipefd);
100 }
101 
102 ATF_TC_CLEANUP(mkdirat_success, tc)
103 {
104 	cleanup();
105 }
106 
107 
108 ATF_TC_WITH_CLEANUP(mkdirat_failure);
109 ATF_TC_HEAD(mkdirat_failure, tc)
110 {
111 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
112 					"mkdirat(2) call");
113 }
114 
115 ATF_TC_BODY(mkdirat_failure, tc)
116 {
117 	ATF_REQUIRE_EQ(0, mkdirat(AT_FDCWD, path, mode));
118 	FILE *pipefd = setup(fds, auclass);
119 	/* Failure reason: directory already exists */
120 	ATF_REQUIRE_EQ(-1, mkdirat(AT_FDCWD, path, mode));
121 	check_audit(fds, failurereg, pipefd);
122 }
123 
124 ATF_TC_CLEANUP(mkdirat_failure, tc)
125 {
126 	cleanup();
127 }
128 
129 
130 ATF_TC_WITH_CLEANUP(mkfifo_success);
131 ATF_TC_HEAD(mkfifo_success, tc)
132 {
133 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
134 					"mkfifo(2) call");
135 }
136 
137 ATF_TC_BODY(mkfifo_success, tc)
138 {
139 	FILE *pipefd = setup(fds, auclass);
140 	ATF_REQUIRE_EQ(0, mkfifo(path, mode));
141 	check_audit(fds, successreg, pipefd);
142 }
143 
144 ATF_TC_CLEANUP(mkfifo_success, tc)
145 {
146 	cleanup();
147 }
148 
149 
150 ATF_TC_WITH_CLEANUP(mkfifo_failure);
151 ATF_TC_HEAD(mkfifo_failure, tc)
152 {
153 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
154 					"mkfifo(2) call");
155 }
156 
157 ATF_TC_BODY(mkfifo_failure, tc)
158 {
159 	ATF_REQUIRE_EQ(0, mkfifo(path, mode));
160 	FILE *pipefd = setup(fds, auclass);
161 	/* Failure reason: FIFO already exists */
162 	ATF_REQUIRE_EQ(-1, mkfifo(path, mode));
163 	check_audit(fds, failurereg, pipefd);
164 }
165 
166 ATF_TC_CLEANUP(mkfifo_failure, tc)
167 {
168 	cleanup();
169 }
170 
171 
172 ATF_TC_WITH_CLEANUP(mkfifoat_success);
173 ATF_TC_HEAD(mkfifoat_success, tc)
174 {
175 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
176 					"mkfifoat(2) call");
177 }
178 
179 ATF_TC_BODY(mkfifoat_success, tc)
180 {
181 	FILE *pipefd = setup(fds, auclass);
182 	ATF_REQUIRE_EQ(0, mkfifoat(AT_FDCWD, path, mode));
183 	check_audit(fds, successreg, pipefd);
184 }
185 
186 ATF_TC_CLEANUP(mkfifoat_success, tc)
187 {
188 	cleanup();
189 }
190 
191 
192 ATF_TC_WITH_CLEANUP(mkfifoat_failure);
193 ATF_TC_HEAD(mkfifoat_failure, tc)
194 {
195 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
196 					"mkfifoat(2) call");
197 }
198 
199 ATF_TC_BODY(mkfifoat_failure, tc)
200 {
201 	ATF_REQUIRE_EQ(0, mkfifoat(AT_FDCWD, path, mode));
202 	FILE *pipefd = setup(fds, auclass);
203 	/* Failure reason: FIFO already exists */
204 	ATF_REQUIRE_EQ(-1, mkfifoat(AT_FDCWD, path, mode));
205 	check_audit(fds, failurereg, pipefd);
206 }
207 
208 ATF_TC_CLEANUP(mkfifoat_failure, tc)
209 {
210 	cleanup();
211 }
212 
213 
214 ATF_TC_WITH_CLEANUP(mknod_success);
215 ATF_TC_HEAD(mknod_success, tc)
216 {
217 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
218 					"mknod(2) call");
219 }
220 
221 ATF_TC_BODY(mknod_success, tc)
222 {
223 	FILE *pipefd = setup(fds, auclass);
224 	ATF_REQUIRE_EQ(0, mknod(path, S_IFIFO | S_IRWXO, dev));
225 	check_audit(fds, successreg, pipefd);
226 }
227 
228 ATF_TC_CLEANUP(mknod_success, tc)
229 {
230 	cleanup();
231 }
232 
233 
234 ATF_TC_WITH_CLEANUP(mknod_failure);
235 ATF_TC_HEAD(mknod_failure, tc)
236 {
237 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
238 					"mknod(2) call");
239 }
240 
241 ATF_TC_BODY(mknod_failure, tc)
242 {
243 	ATF_REQUIRE_EQ(0, mknod(path, S_IFIFO | S_IRWXO, dev));
244 	FILE *pipefd = setup(fds, auclass);
245 	/* Failure reason: FIFO node already exists */
246 	ATF_REQUIRE_EQ(-1, mknod(path, S_IFIFO | S_IRWXO, dev));
247 	check_audit(fds, failurereg, pipefd);
248 }
249 
250 ATF_TC_CLEANUP(mknod_failure, tc)
251 {
252 	cleanup();
253 }
254 
255 
256 ATF_TC_WITH_CLEANUP(mknodat_success);
257 ATF_TC_HEAD(mknodat_success, tc)
258 {
259 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
260 					"mknodat(2) call");
261 }
262 
263 ATF_TC_BODY(mknodat_success, tc)
264 {
265 	FILE *pipefd = setup(fds, auclass);
266 	ATF_REQUIRE_EQ(0, mknodat(AT_FDCWD, path, S_IFIFO | S_IRWXO, dev));
267 	check_audit(fds, successreg, pipefd);
268 }
269 
270 ATF_TC_CLEANUP(mknodat_success, tc)
271 {
272 	cleanup();
273 }
274 
275 
276 ATF_TC_WITH_CLEANUP(mknodat_failure);
277 ATF_TC_HEAD(mknodat_failure, tc)
278 {
279 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
280 					"mknodat(2) call");
281 }
282 
283 ATF_TC_BODY(mknodat_failure, tc)
284 {
285 	ATF_REQUIRE_EQ(0, mknodat(AT_FDCWD, path, S_IFIFO | S_IRWXO, dev));
286 	FILE *pipefd = setup(fds, auclass);
287 	/* Failure reason: FIFO node already exists */
288 	ATF_REQUIRE_EQ(-1, mknodat(AT_FDCWD, path, S_IFIFO | S_IRWXO, dev));
289 	check_audit(fds, failurereg, pipefd);
290 }
291 
292 ATF_TC_CLEANUP(mknodat_failure, tc)
293 {
294 	cleanup();
295 }
296 
297 
298 ATF_TC_WITH_CLEANUP(rename_success);
299 ATF_TC_HEAD(rename_success, tc)
300 {
301 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
302 					"rename(2) call");
303 }
304 
305 ATF_TC_BODY(rename_success, tc)
306 {
307 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
308 	FILE *pipefd = setup(fds, auclass);
309 	ATF_REQUIRE_EQ(0, rename(path, "renamed"));
310 	check_audit(fds, successreg, pipefd);
311 	close(filedesc);
312 }
313 
314 ATF_TC_CLEANUP(rename_success, tc)
315 {
316 	cleanup();
317 }
318 
319 
320 ATF_TC_WITH_CLEANUP(rename_failure);
321 ATF_TC_HEAD(rename_failure, tc)
322 {
323 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
324 					"rename(2) call");
325 }
326 
327 ATF_TC_BODY(rename_failure, tc)
328 {
329 	FILE *pipefd = setup(fds, auclass);
330 	/* Failure reason: file does not exist */
331 	ATF_REQUIRE_EQ(-1, rename(path, "renamed"));
332 	check_audit(fds, failurereg, pipefd);
333 }
334 
335 ATF_TC_CLEANUP(rename_failure, tc)
336 {
337 	cleanup();
338 }
339 
340 
341 ATF_TC_WITH_CLEANUP(renameat_success);
342 ATF_TC_HEAD(renameat_success, tc)
343 {
344 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
345 					"renameat(2) call");
346 }
347 
348 ATF_TC_BODY(renameat_success, tc)
349 {
350 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
351 	FILE *pipefd = setup(fds, auclass);
352 	ATF_REQUIRE_EQ(0, renameat(AT_FDCWD, path, AT_FDCWD, "renamed"));
353 	check_audit(fds, successreg, pipefd);
354 	close(filedesc);
355 }
356 
357 ATF_TC_CLEANUP(renameat_success, tc)
358 {
359 	cleanup();
360 }
361 
362 
363 ATF_TC_WITH_CLEANUP(renameat_failure);
364 ATF_TC_HEAD(renameat_failure, tc)
365 {
366 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
367 					"renameat(2) call");
368 }
369 
370 ATF_TC_BODY(renameat_failure, tc)
371 {
372 	FILE *pipefd = setup(fds, auclass);
373 	/* Failure reason: file does not exist */
374 	ATF_REQUIRE_EQ(-1, renameat(AT_FDCWD, path, AT_FDCWD, "renamed"));
375 	check_audit(fds, failurereg, pipefd);
376 }
377 
378 ATF_TC_CLEANUP(renameat_failure, tc)
379 {
380 	cleanup();
381 }
382 
383 
384 ATF_TC_WITH_CLEANUP(link_success);
385 ATF_TC_HEAD(link_success, tc)
386 {
387 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
388 					"link(2) call");
389 }
390 
391 ATF_TC_BODY(link_success, tc)
392 {
393 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
394 	FILE *pipefd = setup(fds, auclass);
395 	ATF_REQUIRE_EQ(0, link(path, "hardlink"));
396 	check_audit(fds, successreg, pipefd);
397 	close(filedesc);
398 }
399 
400 ATF_TC_CLEANUP(link_success, tc)
401 {
402 	cleanup();
403 }
404 
405 
406 ATF_TC_WITH_CLEANUP(link_failure);
407 ATF_TC_HEAD(link_failure, tc)
408 {
409 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
410 					"link(2) call");
411 }
412 
413 ATF_TC_BODY(link_failure, tc)
414 {
415 	FILE *pipefd = setup(fds, auclass);
416 	/* Failure reason: file does not exist */
417 	ATF_REQUIRE_EQ(-1, link(path, "hardlink"));
418 	check_audit(fds, failurereg, pipefd);
419 }
420 
421 ATF_TC_CLEANUP(link_failure, tc)
422 {
423 	cleanup();
424 }
425 
426 
427 ATF_TC_WITH_CLEANUP(linkat_success);
428 ATF_TC_HEAD(linkat_success, tc)
429 {
430 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
431 					"linkat(2) call");
432 }
433 
434 ATF_TC_BODY(linkat_success, tc)
435 {
436 	ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
437 	FILE *pipefd = setup(fds, auclass);
438 	ATF_REQUIRE_EQ(0, linkat(AT_FDCWD, path, AT_FDCWD, "hardlink", 0));
439 	check_audit(fds, successreg, pipefd);
440 	close(filedesc);
441 }
442 
443 ATF_TC_CLEANUP(linkat_success, tc)
444 {
445 	cleanup();
446 }
447 
448 
449 ATF_TC_WITH_CLEANUP(linkat_failure);
450 ATF_TC_HEAD(linkat_failure, tc)
451 {
452 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
453 					"linkat(2) call");
454 }
455 
456 ATF_TC_BODY(linkat_failure, tc)
457 {
458 	FILE *pipefd = setup(fds, auclass);
459 	/* Failure reason: file does not exist */
460 	ATF_REQUIRE_EQ(-1, linkat(AT_FDCWD, path, AT_FDCWD, "hardlink", 0));
461 	check_audit(fds, failurereg, pipefd);
462 }
463 
464 ATF_TC_CLEANUP(linkat_failure, tc)
465 {
466 	cleanup();
467 }
468 
469 
470 ATF_TC_WITH_CLEANUP(symlink_success);
471 ATF_TC_HEAD(symlink_success, tc)
472 {
473 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
474 					"symlink(2) call");
475 }
476 
477 ATF_TC_BODY(symlink_success, tc)
478 {
479 	FILE *pipefd = setup(fds, auclass);
480 	ATF_REQUIRE_EQ(0, symlink(path, "symlink"));
481 	check_audit(fds, successreg, pipefd);
482 }
483 
484 ATF_TC_CLEANUP(symlink_success, tc)
485 {
486 	cleanup();
487 }
488 
489 
490 ATF_TC_WITH_CLEANUP(symlink_failure);
491 ATF_TC_HEAD(symlink_failure, tc)
492 {
493 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
494 					"symlink(2) call");
495 }
496 
497 ATF_TC_BODY(symlink_failure, tc)
498 {
499 	ATF_REQUIRE_EQ(0, symlink(path, "symlink"));
500 	FILE *pipefd = setup(fds, auclass);
501 	/* Failure reason: symbolic link already exists */
502 	ATF_REQUIRE_EQ(-1, symlink(path, "symlink"));
503 	check_audit(fds, failurereg, pipefd);
504 }
505 
506 ATF_TC_CLEANUP(symlink_failure, tc)
507 {
508 	cleanup();
509 }
510 
511 
512 ATF_TC_WITH_CLEANUP(symlinkat_success);
513 ATF_TC_HEAD(symlinkat_success, tc)
514 {
515 	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
516 					"symlinkat(2) call");
517 }
518 
519 ATF_TC_BODY(symlinkat_success, tc)
520 {
521 	FILE *pipefd = setup(fds, auclass);
522 	ATF_REQUIRE_EQ(0, symlinkat(path, AT_FDCWD, "symlink"));
523 	check_audit(fds, successreg, pipefd);
524 }
525 
526 ATF_TC_CLEANUP(symlinkat_success, tc)
527 {
528 	cleanup();
529 }
530 
531 
532 ATF_TC_WITH_CLEANUP(symlinkat_failure);
533 ATF_TC_HEAD(symlinkat_failure, tc)
534 {
535 	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
536 					"symlinkat(2) call");
537 }
538 
539 ATF_TC_BODY(symlinkat_failure, tc)
540 {
541 	ATF_REQUIRE_EQ(0, symlinkat(path, AT_FDCWD, "symlink"));
542 	FILE *pipefd = setup(fds, auclass);
543 	/* Failure reason: symbolic link already exists */
544 	ATF_REQUIRE_EQ(-1, symlinkat(path, AT_FDCWD, "symlink"));
545 	check_audit(fds, failurereg, pipefd);
546 }
547 
548 ATF_TC_CLEANUP(symlinkat_failure, tc)
549 {
550 	cleanup();
551 }
552 
553 
554 ATF_TP_ADD_TCS(tp)
555 {
556 	ATF_TP_ADD_TC(tp, mkdir_success);
557 	ATF_TP_ADD_TC(tp, mkdir_failure);
558 	ATF_TP_ADD_TC(tp, mkdirat_success);
559 	ATF_TP_ADD_TC(tp, mkdirat_failure);
560 
561 	ATF_TP_ADD_TC(tp, mkfifo_success);
562 	ATF_TP_ADD_TC(tp, mkfifo_failure);
563 	ATF_TP_ADD_TC(tp, mkfifoat_success);
564 	ATF_TP_ADD_TC(tp, mkfifoat_failure);
565 
566 	ATF_TP_ADD_TC(tp, mknod_success);
567 	ATF_TP_ADD_TC(tp, mknod_failure);
568 	ATF_TP_ADD_TC(tp, mknodat_success);
569 	ATF_TP_ADD_TC(tp, mknodat_failure);
570 
571 	ATF_TP_ADD_TC(tp, rename_success);
572 	ATF_TP_ADD_TC(tp, rename_failure);
573 	ATF_TP_ADD_TC(tp, renameat_success);
574 	ATF_TP_ADD_TC(tp, renameat_failure);
575 
576 	ATF_TP_ADD_TC(tp, link_success);
577 	ATF_TP_ADD_TC(tp, link_failure);
578 	ATF_TP_ADD_TC(tp, linkat_success);
579 	ATF_TP_ADD_TC(tp, linkat_failure);
580 
581 	ATF_TP_ADD_TC(tp, symlink_success);
582 	ATF_TP_ADD_TC(tp, symlink_failure);
583 	ATF_TP_ADD_TC(tp, symlinkat_success);
584 	ATF_TP_ADD_TC(tp, symlinkat_failure);
585 
586 	return (atf_no_error());
587 }
588