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