xref: /illumos-gate/usr/src/uts/common/os/audit_core.c (revision 23a1ccea)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/param.h>
27 #include <sys/types.h>
28 #include <sys/time.h>
29 #include <sys/kmem.h>
30 #include <sys/proc.h>
31 #include <sys/vnode.h>
32 #include <sys/file.h>
33 #include <sys/user.h>
34 #include <sys/stropts.h>
35 #include <sys/systm.h>
36 #include <sys/pathname.h>
37 #include <sys/debug.h>
38 #include <sys/cred_impl.h>
39 #include <sys/zone.h>
40 #include <sys/modctl.h>
41 #include <sys/sysconf.h>
42 #include <c2/audit.h>
43 #include <c2/audit_kernel.h>
44 #include <c2/audit_kevents.h>
45 #include <c2/audit_record.h>
46 
47 
48 struct p_audit_data *pad0;
49 struct t_audit_data *tad0;
50 
51 extern uint_t num_syscall;		/* size of audit_s2e table */
52 extern kmutex_t pidlock;		/* proc table lock */
53 
54 
55 void
56 audit_init()
57 {
58 	kthread_t	    *au_thread;
59 	auditinfo_addr_t    *ainfo;
60 	struct audit_path   apempty;
61 
62 	/*
63 	 * If the c2audit module is explicitely excluded in /etc/system,
64 	 * it cannot be loaded later (e.g. using modload). Make a notice
65 	 * that the module won't be present and do nothing.
66 	 */
67 
68 	if (mod_sysctl(SYS_CHECK_EXCLUDE, "c2audit") != 0) {
69 		audit_active = C2AUDIT_DISABLED;
70 		return;
71 	}
72 
73 	/* c2audit module can be loaded anytime */
74 	audit_active = C2AUDIT_UNLOADED;
75 
76 	/* initialize the process audit data (pad) memory allocator */
77 	au_pad_init();
78 
79 	/* initialize the zone audit context */
80 	au_zone_setup();
81 
82 	/* inital thread structure */
83 	tad0 = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
84 
85 	/* initial process structure */
86 	pad0 = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
87 	bzero(&pad0->pad_data, sizeof (pad0->pad_data));
88 
89 	curthread->t_audit_data = tad0;
90 	curproc->p_audit_data = pad0;
91 
92 	/*
93 	 * The kernel allocates a bunch of threads make sure they have
94 	 * a valid tad
95 	 */
96 
97 	mutex_enter(&pidlock);
98 
99 	au_thread = curthread;
100 	do {
101 		if (T2A(au_thread) == NULL) {
102 			T2A(au_thread) = tad0;
103 		}
104 		au_thread = au_thread->t_next;
105 	} while (au_thread != curthread);
106 
107 	tad0->tad_ad = NULL;
108 	mutex_exit(&pidlock);
109 
110 	/*
111 	 * Initialize audit context in our cred (kcred).
112 	 * No copy-on-write needed here because it's so early in init.
113 	 */
114 
115 	ainfo = crgetauinfo_modifiable(kcred);
116 	ASSERT(ainfo != NULL);
117 	bzero(ainfo, sizeof (auditinfo_addr_t));
118 	ainfo->ai_auid = AU_NOAUDITID;
119 
120 	/* fabricate an empty audit_path to extend */
121 	apempty.audp_cnt = 0;
122 	apempty.audp_sect[0] = (char *)(&apempty.audp_sect[1]);
123 	pad0->pad_root = au_pathdup(&apempty, 1, 2);
124 	bcopy("/", pad0->pad_root->audp_sect[0], 2);
125 	au_pathhold(pad0->pad_root);
126 	pad0->pad_cwd = pad0->pad_root;
127 }
128 
129 /*
130  * Check for any pending changes to the audit context for the given proc.
131  * p_crlock and pad_lock for the process are acquired here. Caller is
132  * responsible for assuring the process doesn't go away. If context is
133  * updated, the specified cralloc'ed cred will be used, otherwise it's freed.
134  * If no cred is given, it will be cralloc'ed here and caller assures that
135  * it is safe to allocate memory.
136  */
137 
138 void
139 audit_update_context(proc_t *p, cred_t *ncr)
140 {
141 	struct p_audit_data *pad;
142 	cred_t *newcred = ncr;
143 
144 	pad = P2A(p);
145 	if (pad == NULL) {
146 		if (newcred != NULL)
147 			crfree(newcred);
148 		return;
149 	}
150 
151 	/* If a mask update is pending, take care of it. */
152 	if (pad->pad_flags & PAD_SETMASK) {
153 		auditinfo_addr_t *ainfo;
154 
155 		if (newcred == NULL)
156 			newcred = cralloc();
157 
158 		mutex_enter(&pad->pad_lock);
159 		/* the condition may have been handled by the time we lock */
160 		if (pad->pad_flags & PAD_SETMASK) {
161 			ainfo = crgetauinfo_modifiable(newcred);
162 			if (ainfo == NULL) {
163 				mutex_enter(&pad->pad_lock);
164 				crfree(newcred);
165 				return;
166 			}
167 
168 			mutex_enter(&p->p_crlock);
169 			crcopy_to(p->p_cred, newcred);
170 			p->p_cred = newcred;
171 
172 			ainfo->ai_mask = pad->pad_newmask;
173 
174 			/* Unlock and cleanup. */
175 			mutex_exit(&p->p_crlock);
176 			pad->pad_flags &= ~PAD_SETMASK;
177 
178 			/*
179 			 * For curproc, assure that our thread points to right
180 			 * cred, so CRED() will be correct. Otherwise, no need
181 			 * to broadcast changes (via set_proc_pre_sys), since
182 			 * t_pre_sys is ALWAYS on when audit is enabled... due
183 			 * to syscall auditing.
184 			 */
185 			if (p == curproc)
186 				crset(p, newcred);
187 			else
188 				crfree(newcred);
189 		} else {
190 			crfree(newcred);
191 		}
192 		mutex_exit(&pad->pad_lock);
193 	} else {
194 		if (newcred != NULL)
195 			crfree(newcred);
196 	}
197 }
198 
199 /*
200  * ROUTINE:	AUDIT_NEWPROC
201  * PURPOSE:	initialize the child p_audit_data structure
202  * CALLBY:	GETPROC
203  * NOTE:	All threads for the parent process are locked at this point.
204  *		We are essentially running singled threaded for this reason.
205  *		GETPROC is called when system creates a new process.
206  *		By the time AUDIT_NEWPROC is called, the child proc
207  *		structure has already been initialized. What we need
208  *		to do is to allocate the child p_audit_data and
209  *		initialize it with the content of current parent process.
210  */
211 
212 void
213 audit_newproc(struct proc *cp)	/* initialized child proc structure */
214 {
215 	p_audit_data_t *pad;	/* child process audit data */
216 	p_audit_data_t *opad;	/* parent process audit data */
217 
218 	pad = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
219 
220 	P2A(cp) = pad;
221 
222 	opad = P2A(curproc);
223 
224 	/*
225 	 * copy the audit data. Note that all threads of current
226 	 *   process have been "held". Thus there is no race condition
227 	 *   here with mutiple threads trying to alter the cwrd
228 	 *   structure (such as releasing it).
229 	 *
230 	 *   The audit context in the cred is "duplicated" for the new
231 	 *   proc by elsewhere crhold'ing the parent's cred which it shares.
232 	 *
233 	 *   We still want to hold things since auditon() [A_SETUMASK,
234 	 *   A_SETSMASK] could be walking through the processes to
235 	 *   update things.
236 	 */
237 	mutex_enter(&opad->pad_lock);	/* lock opad structure during copy */
238 	pad->pad_data = opad->pad_data;	/* copy parent's process audit data */
239 	au_pathhold(pad->pad_root);
240 	au_pathhold(pad->pad_cwd);
241 	mutex_exit(&opad->pad_lock);	/* current proc will keep cwrd open */
242 
243 	/*
244 	 * If we are in the limited mode, there is nothing to audit and
245 	 * there could not have been anything to audit, since it is not
246 	 * possible to switch from the full mode into the limited mode
247 	 * once the full mode is set.
248 	 */
249 	if (audit_active != C2AUDIT_LOADED)
250 		return;
251 
252 	/*
253 	 * finish auditing of parent here so that it will be done
254 	 * before child has a chance to run. We include the child
255 	 * pid since the return value in the return token is a dummy
256 	 * one and contains no useful information (it is included to
257 	 * make the audit record structure consistant).
258 	 *
259 	 * tad_flag is set if auditing is on
260 	 */
261 	if (((t_audit_data_t *)T2A(curthread))->tad_flag)
262 		au_uwrite(au_to_arg32(0, "child PID", (uint32_t)cp->p_pid));
263 
264 	/*
265 	 * finish up audit record generation here because child process
266 	 * is set to run before parent process. We distinguish here
267 	 * between FORK, FORK1, or VFORK by the saved system call ID.
268 	 */
269 	audit_finish(0, ((t_audit_data_t *)T2A(curthread))->tad_scid, 0, 0);
270 }
271 
272 /*
273  * ROUTINE:	AUDIT_PFREE
274  * PURPOSE:	deallocate the per-process udit data structure
275  * CALLBY:	EXIT
276  *		FORK_FAIL
277  * NOTE:	all lwp except current one have stopped in SEXITLWPS
278  * 		why we are single threaded?
279  *		. all lwp except current one have stopped in SEXITLWPS.
280  */
281 
282 void
283 audit_pfree(struct proc *p)		/* proc structure to be freed */
284 
285 {	/* AUDIT_PFREE */
286 
287 	p_audit_data_t *pad;
288 
289 	pad = P2A(p);
290 
291 	/* better be a per process audit data structure */
292 	ASSERT(pad != (p_audit_data_t *)0);
293 
294 	if (pad == pad0) {
295 		return;
296 	}
297 
298 	/* deallocate all auditing resources for this process */
299 	au_pathrele(pad->pad_root);
300 	au_pathrele(pad->pad_cwd);
301 
302 	/*
303 	 * Since the pad structure is completely overwritten after alloc,
304 	 * we don't bother to clear it.
305 	 */
306 
307 	kmem_cache_free(au_pad_cache, pad);
308 }
309 
310 /*
311  * ROUTINE:	AUDIT_THREAD_CREATE
312  * PURPOSE:	allocate per-process thread audit data structure
313  * CALLBY:	THREAD_CREATE
314  * NOTE:	This is called just after *t was bzero'd.
315  *		We are single threaded in this routine.
316  * TODO:
317  * QUESTION:
318  */
319 
320 void
321 audit_thread_create(kthread_id_t t)
322 {
323 	t_audit_data_t *tad;	/* per-thread audit data */
324 
325 	tad = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
326 
327 	T2A(t) = tad;		/* set up thread audit data ptr */
328 	tad->tad_thread = t;	/* back ptr to thread: DEBUG */
329 }
330 
331 /*
332  * ROUTINE:	AUDIT_THREAD_FREE
333  * PURPOSE:	free the per-thread audit data structure
334  * CALLBY:	THREAD_FREE
335  * NOTE:	most thread data is clear after return
336  */
337 
338 void
339 audit_thread_free(kthread_t *t)
340 {
341 	t_audit_data_t *tad;
342 	au_defer_info_t	*attr;
343 
344 	tad = T2A(t);
345 
346 	/* thread audit data must still be set */
347 
348 	if (tad == tad0) {
349 		return;
350 	}
351 
352 	if (tad == NULL) {
353 		return;
354 	}
355 
356 	t->t_audit_data = 0;
357 
358 	/* must not have any audit record residual */
359 	ASSERT(tad->tad_ad == NULL);
360 
361 	/* saved path must be empty */
362 	ASSERT(tad->tad_aupath == NULL);
363 
364 	if (tad->tad_atpath)
365 		au_pathrele(tad->tad_atpath);
366 
367 	if (audit_active == C2AUDIT_LOADED) {
368 		attr = tad->tad_defer_head;
369 		while (attr != NULL) {
370 			au_defer_info_t	*tmp_attr = attr;
371 
372 			au_free_rec(attr->audi_ad);
373 
374 			attr = attr->audi_next;
375 			kmem_free(tmp_attr, sizeof (au_defer_info_t));
376 		}
377 	}
378 
379 	kmem_free(tad, sizeof (*tad));
380 }
381 
382 /*
383  * ROUTINE:	AUDIT_FALLOC
384  * PURPOSE:	allocating a new file structure
385  * CALLBY:	FALLOC
386  * NOTE:	file structure already initialized
387  * TODO:
388  * QUESTION:
389  */
390 
391 void
392 audit_falloc(struct file *fp)
393 {	/* AUDIT_FALLOC */
394 
395 	f_audit_data_t *fad;
396 
397 	/* allocate per file audit structure if there a'int any */
398 	ASSERT(F2A(fp) == NULL);
399 
400 	fad = kmem_zalloc(sizeof (struct f_audit_data), KM_SLEEP);
401 
402 	F2A(fp) = fad;
403 
404 	fad->fad_thread = curthread; 	/* file audit data back ptr; DEBUG */
405 }
406 
407 /*
408  * ROUTINE:	AUDIT_UNFALLOC
409  * PURPOSE:	deallocate file audit data structure
410  * CALLBY:	CLOSEF
411  *		UNFALLOC
412  * NOTE:
413  * TODO:
414  * QUESTION:
415  */
416 
417 void
418 audit_unfalloc(struct file *fp)
419 {
420 	f_audit_data_t *fad;
421 
422 	fad = F2A(fp);
423 
424 	if (!fad) {
425 		return;
426 	}
427 	if (fad->fad_aupath != NULL) {
428 		au_pathrele(fad->fad_aupath);
429 	}
430 	fp->f_audit_data = 0;
431 	kmem_free(fad, sizeof (struct f_audit_data));
432 }
433 
434 uint32_t
435 audit_getstate()
436 {
437 	return (audit_active == C2AUDIT_LOADED &&
438 	    ((AU_AUDIT_MASK) & U2A(u)->tad_audit));
439 }
440