xref: /illumos-gate/usr/src/uts/common/os/audit_core.c (revision 6a634c9d)
1005d3febSMarek Pospisil /*
2005d3febSMarek Pospisil  * CDDL HEADER START
3005d3febSMarek Pospisil  *
4005d3febSMarek Pospisil  * The contents of this file are subject to the terms of the
5005d3febSMarek Pospisil  * Common Development and Distribution License (the "License").
6005d3febSMarek Pospisil  * You may not use this file except in compliance with the License.
7005d3febSMarek Pospisil  *
8005d3febSMarek Pospisil  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9005d3febSMarek Pospisil  * or http://www.opensolaris.org/os/licensing.
10005d3febSMarek Pospisil  * See the License for the specific language governing permissions
11005d3febSMarek Pospisil  * and limitations under the License.
12005d3febSMarek Pospisil  *
13005d3febSMarek Pospisil  * When distributing Covered Code, include this CDDL HEADER in each
14005d3febSMarek Pospisil  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15005d3febSMarek Pospisil  * If applicable, add the following below this CDDL HEADER, with the
16005d3febSMarek Pospisil  * fields enclosed by brackets "[]" replaced with your own identifying
17005d3febSMarek Pospisil  * information: Portions Copyright [yyyy] [name of copyright owner]
18005d3febSMarek Pospisil  *
19005d3febSMarek Pospisil  * CDDL HEADER END
20005d3febSMarek Pospisil  */
21005d3febSMarek Pospisil /*
22*7a6a8adfSMarek Pospisil  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23005d3febSMarek Pospisil  */
24005d3febSMarek Pospisil 
25005d3febSMarek Pospisil #include <sys/param.h>
26005d3febSMarek Pospisil #include <sys/types.h>
27005d3febSMarek Pospisil #include <sys/time.h>
28005d3febSMarek Pospisil #include <sys/kmem.h>
29005d3febSMarek Pospisil #include <sys/proc.h>
30005d3febSMarek Pospisil #include <sys/vnode.h>
31005d3febSMarek Pospisil #include <sys/file.h>
32005d3febSMarek Pospisil #include <sys/user.h>
33005d3febSMarek Pospisil #include <sys/stropts.h>
34005d3febSMarek Pospisil #include <sys/systm.h>
35005d3febSMarek Pospisil #include <sys/pathname.h>
36005d3febSMarek Pospisil #include <sys/debug.h>
37005d3febSMarek Pospisil #include <sys/cred_impl.h>
38005d3febSMarek Pospisil #include <sys/zone.h>
39005d3febSMarek Pospisil #include <sys/modctl.h>
40005d3febSMarek Pospisil #include <sys/sysconf.h>
41005d3febSMarek Pospisil #include <c2/audit.h>
42005d3febSMarek Pospisil #include <c2/audit_kernel.h>
43005d3febSMarek Pospisil #include <c2/audit_kevents.h>
44005d3febSMarek Pospisil #include <c2/audit_record.h>
45005d3febSMarek Pospisil 
46005d3febSMarek Pospisil 
47005d3febSMarek Pospisil struct p_audit_data *pad0;
48005d3febSMarek Pospisil struct t_audit_data *tad0;
49005d3febSMarek Pospisil 
50005d3febSMarek Pospisil extern uint_t num_syscall;		/* size of audit_s2e table */
51005d3febSMarek Pospisil extern kmutex_t pidlock;		/* proc table lock */
52005d3febSMarek Pospisil 
53005d3febSMarek Pospisil 
54005d3febSMarek Pospisil void
audit_init()55005d3febSMarek Pospisil audit_init()
56005d3febSMarek Pospisil {
57005d3febSMarek Pospisil 	kthread_t	    *au_thread;
58005d3febSMarek Pospisil 	auditinfo_addr_t    *ainfo;
59005d3febSMarek Pospisil 	struct audit_path   apempty;
60005d3febSMarek Pospisil 
61005d3febSMarek Pospisil 	/*
62005d3febSMarek Pospisil 	 * If the c2audit module is explicitely excluded in /etc/system,
63005d3febSMarek Pospisil 	 * it cannot be loaded later (e.g. using modload). Make a notice
64005d3febSMarek Pospisil 	 * that the module won't be present and do nothing.
65005d3febSMarek Pospisil 	 */
66005d3febSMarek Pospisil 
67005d3febSMarek Pospisil 	if (mod_sysctl(SYS_CHECK_EXCLUDE, "c2audit") != 0) {
68005d3febSMarek Pospisil 		audit_active = C2AUDIT_DISABLED;
69005d3febSMarek Pospisil 		return;
70005d3febSMarek Pospisil 	}
71005d3febSMarek Pospisil 
72005d3febSMarek Pospisil 	/* c2audit module can be loaded anytime */
73005d3febSMarek Pospisil 	audit_active = C2AUDIT_UNLOADED;
74005d3febSMarek Pospisil 
75005d3febSMarek Pospisil 	/* initialize the process audit data (pad) memory allocator */
76005d3febSMarek Pospisil 	au_pad_init();
77005d3febSMarek Pospisil 
78005d3febSMarek Pospisil 	/* initialize the zone audit context */
79005d3febSMarek Pospisil 	au_zone_setup();
80005d3febSMarek Pospisil 
81005d3febSMarek Pospisil 	/* inital thread structure */
82005d3febSMarek Pospisil 	tad0 = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
83005d3febSMarek Pospisil 
84005d3febSMarek Pospisil 	/* initial process structure */
85005d3febSMarek Pospisil 	pad0 = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
86005d3febSMarek Pospisil 	bzero(&pad0->pad_data, sizeof (pad0->pad_data));
87005d3febSMarek Pospisil 
88005d3febSMarek Pospisil 	curthread->t_audit_data = tad0;
89005d3febSMarek Pospisil 	curproc->p_audit_data = pad0;
90005d3febSMarek Pospisil 
91005d3febSMarek Pospisil 	/*
92005d3febSMarek Pospisil 	 * The kernel allocates a bunch of threads make sure they have
93005d3febSMarek Pospisil 	 * a valid tad
94005d3febSMarek Pospisil 	 */
95005d3febSMarek Pospisil 
96005d3febSMarek Pospisil 	mutex_enter(&pidlock);
97005d3febSMarek Pospisil 
98005d3febSMarek Pospisil 	au_thread = curthread;
99005d3febSMarek Pospisil 	do {
100005d3febSMarek Pospisil 		if (T2A(au_thread) == NULL) {
101005d3febSMarek Pospisil 			T2A(au_thread) = tad0;
102005d3febSMarek Pospisil 		}
103005d3febSMarek Pospisil 		au_thread = au_thread->t_next;
104005d3febSMarek Pospisil 	} while (au_thread != curthread);
105005d3febSMarek Pospisil 
106005d3febSMarek Pospisil 	tad0->tad_ad = NULL;
107005d3febSMarek Pospisil 	mutex_exit(&pidlock);
108005d3febSMarek Pospisil 
109005d3febSMarek Pospisil 	/*
110005d3febSMarek Pospisil 	 * Initialize audit context in our cred (kcred).
111005d3febSMarek Pospisil 	 * No copy-on-write needed here because it's so early in init.
112005d3febSMarek Pospisil 	 */
113005d3febSMarek Pospisil 
114005d3febSMarek Pospisil 	ainfo = crgetauinfo_modifiable(kcred);
115005d3febSMarek Pospisil 	ASSERT(ainfo != NULL);
116005d3febSMarek Pospisil 	bzero(ainfo, sizeof (auditinfo_addr_t));
117005d3febSMarek Pospisil 	ainfo->ai_auid = AU_NOAUDITID;
118005d3febSMarek Pospisil 
119005d3febSMarek Pospisil 	/* fabricate an empty audit_path to extend */
120005d3febSMarek Pospisil 	apempty.audp_cnt = 0;
121005d3febSMarek Pospisil 	apempty.audp_sect[0] = (char *)(&apempty.audp_sect[1]);
122005d3febSMarek Pospisil 	pad0->pad_root = au_pathdup(&apempty, 1, 2);
123005d3febSMarek Pospisil 	bcopy("/", pad0->pad_root->audp_sect[0], 2);
124005d3febSMarek Pospisil 	au_pathhold(pad0->pad_root);
125005d3febSMarek Pospisil 	pad0->pad_cwd = pad0->pad_root;
126005d3febSMarek Pospisil }
127005d3febSMarek Pospisil 
128005d3febSMarek Pospisil /*
129005d3febSMarek Pospisil  * Check for any pending changes to the audit context for the given proc.
130005d3febSMarek Pospisil  * p_crlock and pad_lock for the process are acquired here. Caller is
131005d3febSMarek Pospisil  * responsible for assuring the process doesn't go away. If context is
132005d3febSMarek Pospisil  * updated, the specified cralloc'ed cred will be used, otherwise it's freed.
133005d3febSMarek Pospisil  * If no cred is given, it will be cralloc'ed here and caller assures that
134005d3febSMarek Pospisil  * it is safe to allocate memory.
135005d3febSMarek Pospisil  */
136005d3febSMarek Pospisil 
137005d3febSMarek Pospisil void
audit_update_context(proc_t * p,cred_t * ncr)138005d3febSMarek Pospisil audit_update_context(proc_t *p, cred_t *ncr)
139005d3febSMarek Pospisil {
140005d3febSMarek Pospisil 	struct p_audit_data *pad;
141005d3febSMarek Pospisil 	cred_t *newcred = ncr;
142005d3febSMarek Pospisil 
143005d3febSMarek Pospisil 	pad = P2A(p);
144005d3febSMarek Pospisil 	if (pad == NULL) {
145005d3febSMarek Pospisil 		if (newcred != NULL)
146005d3febSMarek Pospisil 			crfree(newcred);
147005d3febSMarek Pospisil 		return;
148005d3febSMarek Pospisil 	}
149005d3febSMarek Pospisil 
150005d3febSMarek Pospisil 	/* If a mask update is pending, take care of it. */
151005d3febSMarek Pospisil 	if (pad->pad_flags & PAD_SETMASK) {
152005d3febSMarek Pospisil 		auditinfo_addr_t *ainfo;
153005d3febSMarek Pospisil 
154005d3febSMarek Pospisil 		if (newcred == NULL)
155005d3febSMarek Pospisil 			newcred = cralloc();
156005d3febSMarek Pospisil 
157005d3febSMarek Pospisil 		mutex_enter(&pad->pad_lock);
158005d3febSMarek Pospisil 		/* the condition may have been handled by the time we lock */
159005d3febSMarek Pospisil 		if (pad->pad_flags & PAD_SETMASK) {
160005d3febSMarek Pospisil 			ainfo = crgetauinfo_modifiable(newcred);
161005d3febSMarek Pospisil 			if (ainfo == NULL) {
162*7a6a8adfSMarek Pospisil 				mutex_exit(&pad->pad_lock);
163005d3febSMarek Pospisil 				crfree(newcred);
164005d3febSMarek Pospisil 				return;
165005d3febSMarek Pospisil 			}
166005d3febSMarek Pospisil 
167005d3febSMarek Pospisil 			mutex_enter(&p->p_crlock);
168005d3febSMarek Pospisil 			crcopy_to(p->p_cred, newcred);
169005d3febSMarek Pospisil 			p->p_cred = newcred;
170005d3febSMarek Pospisil 
171005d3febSMarek Pospisil 			ainfo->ai_mask = pad->pad_newmask;
172005d3febSMarek Pospisil 
173005d3febSMarek Pospisil 			/* Unlock and cleanup. */
174005d3febSMarek Pospisil 			mutex_exit(&p->p_crlock);
175005d3febSMarek Pospisil 			pad->pad_flags &= ~PAD_SETMASK;
176005d3febSMarek Pospisil 
177005d3febSMarek Pospisil 			/*
178005d3febSMarek Pospisil 			 * For curproc, assure that our thread points to right
179005d3febSMarek Pospisil 			 * cred, so CRED() will be correct. Otherwise, no need
180005d3febSMarek Pospisil 			 * to broadcast changes (via set_proc_pre_sys), since
181005d3febSMarek Pospisil 			 * t_pre_sys is ALWAYS on when audit is enabled... due
182005d3febSMarek Pospisil 			 * to syscall auditing.
183005d3febSMarek Pospisil 			 */
184005d3febSMarek Pospisil 			if (p == curproc)
185005d3febSMarek Pospisil 				crset(p, newcred);
186005d3febSMarek Pospisil 			else
187005d3febSMarek Pospisil 				crfree(newcred);
188005d3febSMarek Pospisil 		} else {
189005d3febSMarek Pospisil 			crfree(newcred);
190005d3febSMarek Pospisil 		}
191005d3febSMarek Pospisil 		mutex_exit(&pad->pad_lock);
192005d3febSMarek Pospisil 	} else {
193005d3febSMarek Pospisil 		if (newcred != NULL)
194005d3febSMarek Pospisil 			crfree(newcred);
195005d3febSMarek Pospisil 	}
196005d3febSMarek Pospisil }
197005d3febSMarek Pospisil 
198005d3febSMarek Pospisil /*
199005d3febSMarek Pospisil  * ROUTINE:	AUDIT_NEWPROC
200005d3febSMarek Pospisil  * PURPOSE:	initialize the child p_audit_data structure
201005d3febSMarek Pospisil  * CALLBY:	GETPROC
202005d3febSMarek Pospisil  * NOTE:	All threads for the parent process are locked at this point.
203005d3febSMarek Pospisil  *		We are essentially running singled threaded for this reason.
204005d3febSMarek Pospisil  *		GETPROC is called when system creates a new process.
205005d3febSMarek Pospisil  *		By the time AUDIT_NEWPROC is called, the child proc
206005d3febSMarek Pospisil  *		structure has already been initialized. What we need
207005d3febSMarek Pospisil  *		to do is to allocate the child p_audit_data and
208005d3febSMarek Pospisil  *		initialize it with the content of current parent process.
209005d3febSMarek Pospisil  */
210005d3febSMarek Pospisil 
211005d3febSMarek Pospisil void
audit_newproc(struct proc * cp)212005d3febSMarek Pospisil audit_newproc(struct proc *cp)	/* initialized child proc structure */
213005d3febSMarek Pospisil {
214005d3febSMarek Pospisil 	p_audit_data_t *pad;	/* child process audit data */
215005d3febSMarek Pospisil 	p_audit_data_t *opad;	/* parent process audit data */
216005d3febSMarek Pospisil 
217005d3febSMarek Pospisil 	pad = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
218005d3febSMarek Pospisil 
219005d3febSMarek Pospisil 	P2A(cp) = pad;
220005d3febSMarek Pospisil 
221005d3febSMarek Pospisil 	opad = P2A(curproc);
222005d3febSMarek Pospisil 
223005d3febSMarek Pospisil 	/*
224005d3febSMarek Pospisil 	 * copy the audit data. Note that all threads of current
225005d3febSMarek Pospisil 	 *   process have been "held". Thus there is no race condition
226005d3febSMarek Pospisil 	 *   here with mutiple threads trying to alter the cwrd
227005d3febSMarek Pospisil 	 *   structure (such as releasing it).
228005d3febSMarek Pospisil 	 *
229005d3febSMarek Pospisil 	 *   The audit context in the cred is "duplicated" for the new
230005d3febSMarek Pospisil 	 *   proc by elsewhere crhold'ing the parent's cred which it shares.
231005d3febSMarek Pospisil 	 *
232005d3febSMarek Pospisil 	 *   We still want to hold things since auditon() [A_SETUMASK,
233005d3febSMarek Pospisil 	 *   A_SETSMASK] could be walking through the processes to
234005d3febSMarek Pospisil 	 *   update things.
235005d3febSMarek Pospisil 	 */
236005d3febSMarek Pospisil 	mutex_enter(&opad->pad_lock);	/* lock opad structure during copy */
237005d3febSMarek Pospisil 	pad->pad_data = opad->pad_data;	/* copy parent's process audit data */
238005d3febSMarek Pospisil 	au_pathhold(pad->pad_root);
239005d3febSMarek Pospisil 	au_pathhold(pad->pad_cwd);
240005d3febSMarek Pospisil 	mutex_exit(&opad->pad_lock);	/* current proc will keep cwrd open */
241005d3febSMarek Pospisil 
242005d3febSMarek Pospisil 	/*
243005d3febSMarek Pospisil 	 * If we are in the limited mode, there is nothing to audit and
244005d3febSMarek Pospisil 	 * there could not have been anything to audit, since it is not
245005d3febSMarek Pospisil 	 * possible to switch from the full mode into the limited mode
246005d3febSMarek Pospisil 	 * once the full mode is set.
247005d3febSMarek Pospisil 	 */
248005d3febSMarek Pospisil 	if (audit_active != C2AUDIT_LOADED)
249005d3febSMarek Pospisil 		return;
250005d3febSMarek Pospisil 
251005d3febSMarek Pospisil 	/*
252005d3febSMarek Pospisil 	 * finish auditing of parent here so that it will be done
253005d3febSMarek Pospisil 	 * before child has a chance to run. We include the child
254005d3febSMarek Pospisil 	 * pid since the return value in the return token is a dummy
255005d3febSMarek Pospisil 	 * one and contains no useful information (it is included to
256005d3febSMarek Pospisil 	 * make the audit record structure consistant).
257005d3febSMarek Pospisil 	 *
258005d3febSMarek Pospisil 	 * tad_flag is set if auditing is on
259005d3febSMarek Pospisil 	 */
260005d3febSMarek Pospisil 	if (((t_audit_data_t *)T2A(curthread))->tad_flag)
261005d3febSMarek Pospisil 		au_uwrite(au_to_arg32(0, "child PID", (uint32_t)cp->p_pid));
262005d3febSMarek Pospisil 
263005d3febSMarek Pospisil 	/*
264005d3febSMarek Pospisil 	 * finish up audit record generation here because child process
265005d3febSMarek Pospisil 	 * is set to run before parent process. We distinguish here
266005d3febSMarek Pospisil 	 * between FORK, FORK1, or VFORK by the saved system call ID.
267005d3febSMarek Pospisil 	 */
268005d3febSMarek Pospisil 	audit_finish(0, ((t_audit_data_t *)T2A(curthread))->tad_scid, 0, 0);
269005d3febSMarek Pospisil }
270005d3febSMarek Pospisil 
271005d3febSMarek Pospisil /*
272005d3febSMarek Pospisil  * ROUTINE:	AUDIT_PFREE
273005d3febSMarek Pospisil  * PURPOSE:	deallocate the per-process udit data structure
274005d3febSMarek Pospisil  * CALLBY:	EXIT
275005d3febSMarek Pospisil  *		FORK_FAIL
276005d3febSMarek Pospisil  * NOTE:	all lwp except current one have stopped in SEXITLWPS
277005d3febSMarek Pospisil  * 		why we are single threaded?
278005d3febSMarek Pospisil  *		. all lwp except current one have stopped in SEXITLWPS.
279005d3febSMarek Pospisil  */
280005d3febSMarek Pospisil 
281005d3febSMarek Pospisil void
audit_pfree(struct proc * p)282005d3febSMarek Pospisil audit_pfree(struct proc *p)		/* proc structure to be freed */
283005d3febSMarek Pospisil 
284005d3febSMarek Pospisil {	/* AUDIT_PFREE */
285005d3febSMarek Pospisil 
286005d3febSMarek Pospisil 	p_audit_data_t *pad;
287005d3febSMarek Pospisil 
288005d3febSMarek Pospisil 	pad = P2A(p);
289005d3febSMarek Pospisil 
290005d3febSMarek Pospisil 	/* better be a per process audit data structure */
291005d3febSMarek Pospisil 	ASSERT(pad != (p_audit_data_t *)0);
292005d3febSMarek Pospisil 
293005d3febSMarek Pospisil 	if (pad == pad0) {
294005d3febSMarek Pospisil 		return;
295005d3febSMarek Pospisil 	}
296005d3febSMarek Pospisil 
297005d3febSMarek Pospisil 	/* deallocate all auditing resources for this process */
298005d3febSMarek Pospisil 	au_pathrele(pad->pad_root);
299005d3febSMarek Pospisil 	au_pathrele(pad->pad_cwd);
300005d3febSMarek Pospisil 
301005d3febSMarek Pospisil 	/*
302005d3febSMarek Pospisil 	 * Since the pad structure is completely overwritten after alloc,
303005d3febSMarek Pospisil 	 * we don't bother to clear it.
304005d3febSMarek Pospisil 	 */
305005d3febSMarek Pospisil 
306005d3febSMarek Pospisil 	kmem_cache_free(au_pad_cache, pad);
307005d3febSMarek Pospisil }
308005d3febSMarek Pospisil 
309005d3febSMarek Pospisil /*
310005d3febSMarek Pospisil  * ROUTINE:	AUDIT_THREAD_CREATE
311005d3febSMarek Pospisil  * PURPOSE:	allocate per-process thread audit data structure
312005d3febSMarek Pospisil  * CALLBY:	THREAD_CREATE
313005d3febSMarek Pospisil  * NOTE:	This is called just after *t was bzero'd.
314005d3febSMarek Pospisil  *		We are single threaded in this routine.
315005d3febSMarek Pospisil  * TODO:
316005d3febSMarek Pospisil  * QUESTION:
317005d3febSMarek Pospisil  */
318005d3febSMarek Pospisil 
319005d3febSMarek Pospisil void
audit_thread_create(kthread_id_t t)320005d3febSMarek Pospisil audit_thread_create(kthread_id_t t)
321005d3febSMarek Pospisil {
322005d3febSMarek Pospisil 	t_audit_data_t *tad;	/* per-thread audit data */
323005d3febSMarek Pospisil 
324005d3febSMarek Pospisil 	tad = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
325005d3febSMarek Pospisil 
326005d3febSMarek Pospisil 	T2A(t) = tad;		/* set up thread audit data ptr */
327005d3febSMarek Pospisil 	tad->tad_thread = t;	/* back ptr to thread: DEBUG */
328005d3febSMarek Pospisil }
329005d3febSMarek Pospisil 
330005d3febSMarek Pospisil /*
331005d3febSMarek Pospisil  * ROUTINE:	AUDIT_THREAD_FREE
332005d3febSMarek Pospisil  * PURPOSE:	free the per-thread audit data structure
333005d3febSMarek Pospisil  * CALLBY:	THREAD_FREE
334005d3febSMarek Pospisil  * NOTE:	most thread data is clear after return
335005d3febSMarek Pospisil  */
336005d3febSMarek Pospisil 
337005d3febSMarek Pospisil void
audit_thread_free(kthread_t * t)338005d3febSMarek Pospisil audit_thread_free(kthread_t *t)
339005d3febSMarek Pospisil {
340005d3febSMarek Pospisil 	t_audit_data_t *tad;
341005d3febSMarek Pospisil 	au_defer_info_t	*attr;
342005d3febSMarek Pospisil 
343005d3febSMarek Pospisil 	tad = T2A(t);
344005d3febSMarek Pospisil 
345005d3febSMarek Pospisil 	/* thread audit data must still be set */
346005d3febSMarek Pospisil 
347005d3febSMarek Pospisil 	if (tad == tad0) {
348005d3febSMarek Pospisil 		return;
349005d3febSMarek Pospisil 	}
350005d3febSMarek Pospisil 
351005d3febSMarek Pospisil 	if (tad == NULL) {
352005d3febSMarek Pospisil 		return;
353005d3febSMarek Pospisil 	}
354005d3febSMarek Pospisil 
355005d3febSMarek Pospisil 	t->t_audit_data = 0;
356005d3febSMarek Pospisil 
357005d3febSMarek Pospisil 	/* must not have any audit record residual */
358005d3febSMarek Pospisil 	ASSERT(tad->tad_ad == NULL);
359005d3febSMarek Pospisil 
360005d3febSMarek Pospisil 	/* saved path must be empty */
361005d3febSMarek Pospisil 	ASSERT(tad->tad_aupath == NULL);
362005d3febSMarek Pospisil 
363005d3febSMarek Pospisil 	if (tad->tad_atpath)
364005d3febSMarek Pospisil 		au_pathrele(tad->tad_atpath);
365005d3febSMarek Pospisil 
366005d3febSMarek Pospisil 	if (audit_active == C2AUDIT_LOADED) {
367005d3febSMarek Pospisil 		attr = tad->tad_defer_head;
368005d3febSMarek Pospisil 		while (attr != NULL) {
369005d3febSMarek Pospisil 			au_defer_info_t	*tmp_attr = attr;
370005d3febSMarek Pospisil 
371005d3febSMarek Pospisil 			au_free_rec(attr->audi_ad);
372005d3febSMarek Pospisil 
373005d3febSMarek Pospisil 			attr = attr->audi_next;
374005d3febSMarek Pospisil 			kmem_free(tmp_attr, sizeof (au_defer_info_t));
375005d3febSMarek Pospisil 		}
376005d3febSMarek Pospisil 	}
377005d3febSMarek Pospisil 
378005d3febSMarek Pospisil 	kmem_free(tad, sizeof (*tad));
379005d3febSMarek Pospisil }
380005d3febSMarek Pospisil 
381005d3febSMarek Pospisil /*
382005d3febSMarek Pospisil  * ROUTINE:	AUDIT_FALLOC
383005d3febSMarek Pospisil  * PURPOSE:	allocating a new file structure
384005d3febSMarek Pospisil  * CALLBY:	FALLOC
385005d3febSMarek Pospisil  * NOTE:	file structure already initialized
386005d3febSMarek Pospisil  * TODO:
387005d3febSMarek Pospisil  * QUESTION:
388005d3febSMarek Pospisil  */
389005d3febSMarek Pospisil 
390005d3febSMarek Pospisil void
audit_falloc(struct file * fp)391005d3febSMarek Pospisil audit_falloc(struct file *fp)
392005d3febSMarek Pospisil {	/* AUDIT_FALLOC */
393005d3febSMarek Pospisil 
394005d3febSMarek Pospisil 	f_audit_data_t *fad;
395005d3febSMarek Pospisil 
396005d3febSMarek Pospisil 	/* allocate per file audit structure if there a'int any */
397005d3febSMarek Pospisil 	ASSERT(F2A(fp) == NULL);
398005d3febSMarek Pospisil 
399005d3febSMarek Pospisil 	fad = kmem_zalloc(sizeof (struct f_audit_data), KM_SLEEP);
400005d3febSMarek Pospisil 
401005d3febSMarek Pospisil 	F2A(fp) = fad;
402005d3febSMarek Pospisil 
403005d3febSMarek Pospisil 	fad->fad_thread = curthread; 	/* file audit data back ptr; DEBUG */
404005d3febSMarek Pospisil }
405005d3febSMarek Pospisil 
406005d3febSMarek Pospisil /*
407005d3febSMarek Pospisil  * ROUTINE:	AUDIT_UNFALLOC
408005d3febSMarek Pospisil  * PURPOSE:	deallocate file audit data structure
409005d3febSMarek Pospisil  * CALLBY:	CLOSEF
410005d3febSMarek Pospisil  *		UNFALLOC
411005d3febSMarek Pospisil  * NOTE:
412005d3febSMarek Pospisil  * TODO:
413005d3febSMarek Pospisil  * QUESTION:
414005d3febSMarek Pospisil  */
415005d3febSMarek Pospisil 
416005d3febSMarek Pospisil void
audit_unfalloc(struct file * fp)417005d3febSMarek Pospisil audit_unfalloc(struct file *fp)
418005d3febSMarek Pospisil {
419005d3febSMarek Pospisil 	f_audit_data_t *fad;
420005d3febSMarek Pospisil 
421005d3febSMarek Pospisil 	fad = F2A(fp);
422005d3febSMarek Pospisil 
423005d3febSMarek Pospisil 	if (!fad) {
424005d3febSMarek Pospisil 		return;
425005d3febSMarek Pospisil 	}
426005d3febSMarek Pospisil 	if (fad->fad_aupath != NULL) {
427005d3febSMarek Pospisil 		au_pathrele(fad->fad_aupath);
428005d3febSMarek Pospisil 	}
429005d3febSMarek Pospisil 	fp->f_audit_data = 0;
430005d3febSMarek Pospisil 	kmem_free(fad, sizeof (struct f_audit_data));
431005d3febSMarek Pospisil }
432005d3febSMarek Pospisil 
433005d3febSMarek Pospisil uint32_t
audit_getstate()434005d3febSMarek Pospisil audit_getstate()
435005d3febSMarek Pospisil {
436005d3febSMarek Pospisil 	return (audit_active == C2AUDIT_LOADED &&
437005d3febSMarek Pospisil 	    ((AU_AUDIT_MASK) & U2A(u)->tad_audit));
438005d3febSMarek Pospisil }
439