1334592Sasomers/*-
2334592Sasomers * Copyright 2018 Aniket Pandey
3334592Sasomers *
4334592Sasomers * Redistribution and use in source and binary forms, with or without
5334592Sasomers * modification, are permitted provided that the following conditions
6334592Sasomers * are met:
7334592Sasomers * 1. Redistributions of source code must retain the above copyright
8334592Sasomers *    notice, this list of conditions and the following disclaimer.
9334592Sasomers * 2. Redistributions in binary form must reproduce the above copyright
10334592Sasomers *    notice, this list of conditions and the following disclaimer in the
11334592Sasomers *    documentation and/or other materials provided with the distribution.
12334592Sasomers *
13334592Sasomers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14334592Sasomers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15334592Sasomers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16334592Sasomers * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17334592Sasomers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18334592Sasomers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19334592Sasomers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
20334592Sasomers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21334592Sasomers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22334592Sasomers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23334592Sasomers * SUCH DAMAGE.
24334592Sasomers *
25334592Sasomers * $FreeBSD: stable/11/tests/sys/audit/file-close.c 339087 2018-10-02 16:23:33Z asomers $
26334592Sasomers */
27334592Sasomers
28334592Sasomers#include <sys/mman.h>
29334592Sasomers#include <sys/stat.h>
30334592Sasomers
31334592Sasomers#include <atf-c.h>
32334592Sasomers#include <fcntl.h>
33334592Sasomers#include <limits.h>
34334592Sasomers#include <stdint.h>
35334592Sasomers#include <stdlib.h>
36334592Sasomers#include <unistd.h>
37334592Sasomers
38334592Sasomers#include "utils.h"
39334592Sasomers
40334592Sasomersstatic pid_t pid;
41334592Sasomersstatic struct pollfd fds[1];
42334592Sasomersstatic mode_t mode = 0777;
43339087Sasomersstatic int filedesc;
44334592Sasomersstatic char extregex[80];
45334592Sasomersstatic struct stat statbuff;
46334592Sasomersstatic const char *auclass = "cl";
47334592Sasomersstatic const char *path = "fileforaudit";
48334592Sasomersstatic const char *errpath = "dirdoesnotexist/fileforaudit";
49334592Sasomersstatic const char *failurereg = "fileforaudit.*return,failure";
50334592Sasomers
51334592Sasomers
52334592SasomersATF_TC_WITH_CLEANUP(munmap_success);
53334592SasomersATF_TC_HEAD(munmap_success, tc)
54334592Sasomers{
55334592Sasomers	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
56334592Sasomers					"munmap(2) call");
57334592Sasomers}
58334592Sasomers
59334592SasomersATF_TC_BODY(munmap_success, tc)
60334592Sasomers{
61334592Sasomers	pid = getpid();
62334592Sasomers	snprintf(extregex, sizeof(extregex), "munmap.*%d.*return,success", pid);
63334592Sasomers
64334592Sasomers	/* Allocate sample memory, to be removed by munmap(2) */
65334592Sasomers	char *addr = mmap(NULL, sizeof(char), PROT_READ , MAP_ANONYMOUS, -1, 0);
66334592Sasomers	FILE *pipefd = setup(fds, auclass);
67334592Sasomers	ATF_REQUIRE_EQ(0, munmap(addr, sizeof(char)));
68334592Sasomers	check_audit(fds, extregex, pipefd);
69334592Sasomers}
70334592Sasomers
71334592SasomersATF_TC_CLEANUP(munmap_success, tc)
72334592Sasomers{
73334592Sasomers	cleanup();
74334592Sasomers}
75334592Sasomers
76334592Sasomers
77334592SasomersATF_TC_WITH_CLEANUP(munmap_failure);
78334592SasomersATF_TC_HEAD(munmap_failure, tc)
79334592Sasomers{
80334592Sasomers	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
81334592Sasomers					"munmap(2) call");
82334592Sasomers}
83334592Sasomers
84334592SasomersATF_TC_BODY(munmap_failure, tc)
85334592Sasomers{
86334592Sasomers	const char *regex = "munmap.*return,failure : Invalid argument";
87334592Sasomers	FILE *pipefd = setup(fds, auclass);
88334592Sasomers	ATF_REQUIRE_EQ(-1, munmap((void *)SIZE_MAX, -1));
89334592Sasomers	check_audit(fds, regex, pipefd);
90334592Sasomers}
91334592Sasomers
92334592SasomersATF_TC_CLEANUP(munmap_failure, tc)
93334592Sasomers{
94334592Sasomers	cleanup();
95334592Sasomers}
96334592Sasomers
97334592Sasomers
98334592SasomersATF_TC_WITH_CLEANUP(close_success);
99334592SasomersATF_TC_HEAD(close_success, tc)
100334592Sasomers{
101334592Sasomers	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
102334592Sasomers					"close(2) call");
103334592Sasomers}
104334592Sasomers
105334592SasomersATF_TC_BODY(close_success, tc)
106334592Sasomers{
107334592Sasomers	/* File needs to exist to call close(2) */
108334592Sasomers	ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1);
109334592Sasomers	/* Call stat(2) to store the Inode number of 'path' */
110334592Sasomers	ATF_REQUIRE_EQ(0, stat(path, &statbuff));
111334592Sasomers	FILE *pipefd = setup(fds, auclass);
112334592Sasomers	ATF_REQUIRE_EQ(0, close(filedesc));
113334592Sasomers
114334592Sasomers	/* intmax_t to support all architectures */
115334592Sasomers	snprintf(extregex, sizeof(extregex), "close.*%jd.*return,succes",
116334592Sasomers			(intmax_t)statbuff.st_ino);
117334592Sasomers	check_audit(fds, extregex, pipefd);
118334592Sasomers}
119334592Sasomers
120334592SasomersATF_TC_CLEANUP(close_success, tc)
121334592Sasomers{
122334592Sasomers	cleanup();
123334592Sasomers}
124334592Sasomers
125334592Sasomers
126334592SasomersATF_TC_WITH_CLEANUP(close_failure);
127334592SasomersATF_TC_HEAD(close_failure, tc)
128334592Sasomers{
129334592Sasomers	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
130334592Sasomers					"close(2) call");
131334592Sasomers}
132334592Sasomers
133334592SasomersATF_TC_BODY(close_failure, tc)
134334592Sasomers{
135334592Sasomers	const char *regex = "close.*return,failure";
136334592Sasomers	FILE *pipefd = setup(fds, auclass);
137334592Sasomers	/* Failure reason: file does not exist */
138334592Sasomers	ATF_REQUIRE_EQ(-1, close(-1));
139334592Sasomers	check_audit(fds, regex, pipefd);
140334592Sasomers}
141334592Sasomers
142334592SasomersATF_TC_CLEANUP(close_failure, tc)
143334592Sasomers{
144334592Sasomers	cleanup();
145334592Sasomers}
146334592Sasomers
147334592Sasomers
148334592SasomersATF_TC_WITH_CLEANUP(closefrom_success);
149334592SasomersATF_TC_HEAD(closefrom_success, tc)
150334592Sasomers{
151334592Sasomers	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
152334592Sasomers					"closefrom(2) call");
153334592Sasomers}
154334592Sasomers
155334592SasomersATF_TC_BODY(closefrom_success, tc)
156334592Sasomers{
157334592Sasomers	const char *regex = "closefrom.*return,success";
158334592Sasomers	FILE *pipefd = setup(fds, auclass);
159334592Sasomers	/* closefrom(2) returns 'void' */
160334592Sasomers	closefrom(INT_MAX);
161334592Sasomers	check_audit(fds, regex, pipefd);
162334592Sasomers}
163334592Sasomers
164334592SasomersATF_TC_CLEANUP(closefrom_success, tc)
165334592Sasomers{
166334592Sasomers	cleanup();
167334592Sasomers}
168334592Sasomers
169334592Sasomers
170334592SasomersATF_TC_WITH_CLEANUP(revoke_success);
171334592SasomersATF_TC_HEAD(revoke_success, tc)
172334592Sasomers{
173334592Sasomers	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
174334592Sasomers					"revoke(2) call");
175334592Sasomers}
176334592Sasomers
177334592SasomersATF_TC_BODY(revoke_success, tc)
178334592Sasomers{
179334592Sasomers	char *ptyname;
180334592Sasomers	pid = getpid();
181334592Sasomers	snprintf(extregex, sizeof(extregex), "revoke.*%d.*return,success", pid);
182334592Sasomers
183334592Sasomers	/* Obtain a pseudo terminal and get the path to slave device */
184334592Sasomers	ATF_REQUIRE((filedesc = posix_openpt(O_RDWR | O_NOCTTY)) != -1);
185334592Sasomers	ATF_REQUIRE((ptyname = ptsname(filedesc)) != NULL);
186334592Sasomers
187334592Sasomers	FILE *pipefd = setup(fds, auclass);
188334592Sasomers	ATF_REQUIRE_EQ(0, revoke(ptyname));
189334592Sasomers	check_audit(fds, extregex, pipefd);
190339087Sasomers	close(filedesc);
191334592Sasomers}
192334592Sasomers
193334592SasomersATF_TC_CLEANUP(revoke_success, tc)
194334592Sasomers{
195334592Sasomers	cleanup();
196334592Sasomers}
197334592Sasomers
198334592Sasomers
199334592SasomersATF_TC_WITH_CLEANUP(revoke_failure);
200334592SasomersATF_TC_HEAD(revoke_failure, tc)
201334592Sasomers{
202334592Sasomers	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
203334592Sasomers					"revoke(2) call");
204334592Sasomers}
205334592Sasomers
206334592SasomersATF_TC_BODY(revoke_failure, tc)
207334592Sasomers{
208334592Sasomers	FILE *pipefd = setup(fds, auclass);
209334592Sasomers	/* Failure reason: file does not exist */
210334592Sasomers	ATF_REQUIRE_EQ(-1, revoke(errpath));
211334592Sasomers	check_audit(fds, failurereg, pipefd);
212334592Sasomers}
213334592Sasomers
214334592SasomersATF_TC_CLEANUP(revoke_failure, tc)
215334592Sasomers{
216334592Sasomers	cleanup();
217334592Sasomers}
218334592Sasomers
219334592Sasomers
220334592SasomersATF_TP_ADD_TCS(tp)
221334592Sasomers{
222334592Sasomers	ATF_TP_ADD_TC(tp, munmap_success);
223334592Sasomers	ATF_TP_ADD_TC(tp, munmap_failure);
224334592Sasomers
225334592Sasomers	ATF_TP_ADD_TC(tp, close_success);
226334592Sasomers	ATF_TP_ADD_TC(tp, close_failure);
227334592Sasomers	ATF_TP_ADD_TC(tp, closefrom_success);
228334592Sasomers
229334592Sasomers	ATF_TP_ADD_TC(tp, revoke_success);
230334592Sasomers	ATF_TP_ADD_TC(tp, revoke_failure);
231334592Sasomers
232334592Sasomers	return (atf_no_error());
233334592Sasomers}
234