xref: /illumos-gate/usr/src/uts/common/c2/audit_start.c (revision 60afd2f6)
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 /*
27  * This file contains the envelope code for system call auditing.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/time.h>
33 #include <sys/kmem.h>
34 #include <sys/proc.h>
35 #include <sys/vnode.h>
36 #include <sys/file.h>
37 #include <sys/user.h>
38 #include <sys/stropts.h>
39 #include <sys/systm.h>
40 #include <sys/pathname.h>
41 #include <sys/debug.h>
42 #include <sys/cred.h>
43 #include <sys/zone.h>
44 #include <c2/audit.h>
45 #include <c2/audit_kernel.h>
46 #include <c2/audit_kevents.h>
47 #include <c2/audit_record.h>
48 #include "audit_door_infc.h"
49 
50 extern uint_t num_syscall;		/* size of audit_s2e table */
51 extern kmutex_t pidlock;		/* proc table lock */
52 
53 /*
54  * Obsolete and ignored - Historically, the 'set c2audit:audit_load=1' entry
55  * in /etc/system enabled auditing. The No Reboot Audit project does not
56  * use this entry. However, to prevent the system from printing warning
57  * messages, the audit_load entry is being left in /etc/system. It will be
58  * removed when there is a small chance that the entry is used on currently
59  * running systems.
60  */
61 int audit_load = 0;
62 
63 kmutex_t module_lock;			/* audit_module_state lock */
64 
65 /*
66  * Das Boot. Initialize first process. Also generate an audit record indicating
67  * that the system has been booted.
68  */
69 void
70 audit_init_module()
71 {
72 	token_t *rp = NULL;
73 	label_t jb;
74 	t_audit_data_t *tad = U2A(u);
75 
76 	/*
77 	 * Solaris Auditing module is being loaded -> change the state. The lock
78 	 * is here to prevent memory leaks caused by multiple initializations.
79 	 */
80 	mutex_enter(&module_lock);
81 	if (audit_active != C2AUDIT_UNLOADED) {
82 		mutex_exit(&module_lock);
83 		return;
84 	}
85 	audit_active = C2AUDIT_LOADED;
86 	mutex_exit(&module_lock);
87 
88 	/* initialize memory allocators */
89 	au_mem_init();
90 
91 	/*
92 	 * setup environment for asynchronous auditing. We can't use
93 	 * audit_async_start() here since it assumes the audit system
94 	 * has been started via auditd(1m). auditd sets the variable,
95 	 * auk_auditstate, to indicate audit record generation should
96 	 * commence. Here we want to always generate an audit record.
97 	 */
98 	if (setjmp(&jb)) {
99 		/* process audit policy (AUDIT_AHLT) for asynchronous events */
100 		audit_async_drop((caddr_t *)(&rp), 0);
101 		return;
102 	}
103 
104 	ASSERT(tad->tad_errjmp == NULL);
105 	tad->tad_errjmp = (void *)&jb;
106 	tad->tad_ctrl |= PAD_ERRJMP;
107 
108 	/* generate a system-booted audit record */
109 	au_write((caddr_t *)&rp, au_to_text("booting kernel"));
110 	audit_async_finish((caddr_t *)&rp, AUE_SYSTEMBOOT, NULL,
111 	    &(p0.p_user.u_start));
112 }
113 
114 
115 /*
116  * Enter system call. Do any necessary setup here. allocate resouces, etc.
117  */
118 
119 #include <sys/syscall.h>
120 
121 
122 /*ARGSUSED*/
123 int
124 audit_start(
125 	unsigned type,
126 	unsigned scid,
127 	uint32_t audit_state,
128 	int error,
129 	klwp_t *lwp)
130 {
131 	struct t_audit_data	*tad;
132 	au_kcontext_t		*kctx;
133 
134 	tad = U2A(u);
135 	ASSERT(tad != NULL);
136 
137 	/* Remember the audit state in the cache */
138 	tad->tad_audit = audit_state;
139 
140 	if (error) {
141 		tad->tad_ctrl = 0;
142 		tad->tad_flag = 0;
143 		return (0);
144 	}
145 
146 	audit_update_context(curproc, NULL);
147 
148 	/*
149 	 * if this is an indirect system call then don't do anything.
150 	 * audit_start will be called again from indir() in trap.c
151 	 */
152 	if (scid == 0) {
153 		tad->tad_ctrl = 0;
154 		tad->tad_flag = 0;
155 		return (0);
156 	}
157 	if (scid >= num_syscall)
158 		scid = 0;
159 
160 	/*
161 	 * we can no longer depend on a valid lwp_ap, so we need to
162 	 * copy the syscall args as future audit stuff may need them.
163 	 */
164 	(void) save_syscall_args();
165 
166 	/*
167 	 * We need to gather paths for certain system calls even if they are
168 	 * not audited so that we can audit the various f* calls and be
169 	 * sure to have a CWD and CAR. Thus we thus set tad_ctrl over the
170 	 * system call regardless if the call is audited or not.
171 	 * We allow the event specific initial processing routines (au_init)
172 	 * to adjust the tad_ctrl as necessary.
173 	 */
174 	tad->tad_ctrl   = audit_s2e[scid].au_ctrl;
175 	tad->tad_scid   = scid;
176 
177 	/* get basic event for system call */
178 	tad->tad_event = audit_s2e[scid].au_event;
179 	if (audit_s2e[scid].au_init != (au_event_t)AUE_NULL) {
180 		/* get specific event */
181 		tad->tad_event = (*audit_s2e[scid].au_init)(tad->tad_event);
182 	}
183 
184 	kctx = GET_KCTX_PZ;
185 
186 	/* now do preselection. Audit or not to Audit, that is the question */
187 	if ((tad->tad_flag = auditme(kctx, tad,
188 	    kctx->auk_ets[tad->tad_event])) == 0) {
189 		/*
190 		 * we assume that audit_finish will always be called.
191 		 */
192 		return (0);
193 	}
194 
195 	/*
196 	 * if auditing not enabled, then don't generate an audit record
197 	 * and don't count it.
198 	 */
199 	if (audit_state & ~(AUC_AUDITING | AUC_INIT_AUDIT)) {
200 		/*
201 		 * we assume that audit_finish will always be called.
202 		 */
203 		tad->tad_flag = 0;
204 		return (0);
205 	}
206 
207 	/*
208 	 * audit daemon has informed us that there is no longer any
209 	 * space left to hold audit records. We decide here if records
210 	 * should be dropped (but counted).
211 	 */
212 	if (audit_state == AUC_NOSPACE) {
213 		if ((kctx->auk_policy & AUDIT_CNT) ||
214 		    (kctx->auk_policy & AUDIT_SCNT)) {
215 			/* assume that audit_finish will always be called. */
216 			tad->tad_flag = 0;
217 
218 			/* just count # of dropped audit records */
219 			AS_INC(as_dropped, 1, kctx);
220 
221 			return (0);
222 		}
223 	}
224 
225 	tad->tad_evmod  = 0;
226 
227 	if (audit_s2e[scid].au_start != NULL) {
228 		/* do start of system call processing */
229 		(*audit_s2e[scid].au_start)(tad);
230 	}
231 
232 	return (0);
233 }
234 
235 /*
236  * system call has completed. Now determine if we genearate an audit record
237  * or not.
238  */
239 /*ARGSUSED*/
240 void
241 audit_finish(
242 	unsigned type,
243 	unsigned scid,
244 	int error,
245 	rval_t *rval)
246 {
247 	struct t_audit_data *tad;
248 	int	flag;
249 	au_defer_info_t	*attr;
250 	au_kcontext_t *kctx = GET_KCTX_PZ;
251 
252 	tad = U2A(u);
253 
254 	/*
255 	 * Process all deferred events first.
256 	 */
257 	attr = tad->tad_defer_head;
258 	while (attr != NULL) {
259 		au_defer_info_t	*tmp_attr = attr;
260 
261 		au_close_time(kctx, (token_t *)attr->audi_ad, attr->audi_flag,
262 		    attr->audi_e_type, attr->audi_e_mod, &(attr->audi_atime));
263 
264 		attr = attr->audi_next;
265 		kmem_free(tmp_attr, sizeof (au_defer_info_t));
266 	}
267 	tad->tad_defer_head = tad->tad_defer_tail = NULL;
268 
269 	if (tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) {
270 		/*
271 		 * clear the ctrl flag so that we don't have spurious
272 		 * collection of audit information.
273 		 */
274 		tad->tad_scid  = 0;
275 		tad->tad_event = 0;
276 		tad->tad_evmod = 0;
277 		tad->tad_ctrl  = 0;
278 		tad->tad_audit = AUC_UNSET;
279 		ASSERT(tad->tad_aupath == NULL);
280 		return;
281 	}
282 
283 	scid = tad->tad_scid;
284 
285 	/*
286 	 * Perform any extra processing and determine if we are
287 	 * really going to generate any audit record.
288 	 */
289 	if (audit_s2e[scid].au_finish != NULL) {
290 		/* do any post system call processing */
291 		(*audit_s2e[scid].au_finish)(tad, error, rval);
292 	}
293 	if (tad->tad_flag) {
294 		tad->tad_flag = 0;
295 
296 		if (flag = audit_success(kctx, tad, error, NULL)) {
297 			unsigned int sy_flags;
298 			cred_t *cr = CRED();
299 			const auditinfo_addr_t *ainfo = crgetauinfo(cr);
300 
301 			ASSERT(ainfo != NULL);
302 
303 			/* Add subject information */
304 			AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
305 
306 			if (tad->tad_evmod & PAD_SPRIVUSE) {
307 				au_write(&(u_ad),
308 				    au_to_privset("", &tad->tad_sprivs,
309 				    AUT_UPRIV, 1));
310 			}
311 
312 			if (tad->tad_evmod & PAD_FPRIVUSE) {
313 				au_write(&(u_ad),
314 				    au_to_privset("", &tad->tad_fprivs,
315 				    AUT_UPRIV, 0));
316 			}
317 
318 			/* Add a return token */
319 #ifdef	_SYSCALL32_IMPL
320 			if (lwp_getdatamodel(ttolwp(curthread)) ==
321 			    DATAMODEL_NATIVE) {
322 				sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
323 			} else {
324 				sy_flags =
325 				    sysent32[scid].sy_flags & SE_RVAL_MASK;
326 			}
327 #else	/* _SYSCALL64_IMPL */
328 			sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
329 #endif   /* _SYSCALL32_IMPL */
330 
331 			if (sy_flags == SE_32RVAL1) {
332 				if (type == 0) {
333 					au_write(&(u_ad),
334 					    au_to_return32(error, 0));
335 				} else {
336 					au_write(&(u_ad), au_to_return32(error,
337 					    rval->r_val1));
338 				}
339 			}
340 			if (sy_flags == (SE_32RVAL2|SE_32RVAL1)) {
341 				if (type == 0) {
342 					au_write(&(u_ad),
343 					    au_to_return32(error, 0));
344 				} else {
345 					au_write(&(u_ad),
346 					    au_to_return32(error,
347 					    rval->r_val1));
348 #ifdef NOTYET	/* for possible future support */
349 					au_write(&(u_ad), au_to_return32(error,
350 					    rval->r_val2));
351 #endif
352 				}
353 			}
354 			if (sy_flags == SE_64RVAL) {
355 				if (type == 0) {
356 					au_write(&(u_ad),
357 					    au_to_return64(error, 0));
358 				} else {
359 					au_write(&(u_ad), au_to_return64(error,
360 					    rval->r_vals));
361 				}
362 			}
363 
364 			AS_INC(as_generated, 1, kctx);
365 			AS_INC(as_kernel, 1, kctx);
366 		}
367 
368 		/* Close up everything */
369 		au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod,
370 		    NULL);
371 	}
372 
373 	ASSERT(u_ad == NULL);
374 
375 	/* free up any space remaining with the path's */
376 	if (tad->tad_aupath != NULL) {
377 		au_pathrele(tad->tad_aupath);
378 		tad->tad_aupath = NULL;
379 		tad->tad_vn = NULL;
380 	}
381 
382 	/* free up any space remaining with openat path's */
383 	if (tad->tad_atpath) {
384 		au_pathrele(tad->tad_atpath);
385 		tad->tad_atpath = NULL;
386 	}
387 
388 	/*
389 	 * clear the ctrl flag so that we don't have spurious collection of
390 	 * audit information.
391 	 */
392 	tad->tad_scid  = 0;
393 	tad->tad_event = 0;
394 	tad->tad_evmod = 0;
395 	tad->tad_ctrl  = 0;
396 	tad->tad_audit = AUC_UNSET;
397 }
398 
399 int
400 audit_success(au_kcontext_t *kctx, struct t_audit_data *tad, int error,
401     cred_t *cr)
402 {
403 	au_state_t ess;
404 	au_state_t esf;
405 	au_mask_t amask;
406 	const auditinfo_addr_t *ainfo;
407 
408 	ess = esf = kctx->auk_ets[tad->tad_event];
409 
410 	if (error)
411 		tad->tad_evmod |= PAD_FAILURE;
412 
413 	/* see if we really want to generate an audit record */
414 	if (tad->tad_ctrl & PAD_NOAUDIT)
415 		return (0);
416 
417 	/*
418 	 * nfs operation and we're auditing privilege or MAC. This
419 	 * is so we have a client audit record to match a nfs server
420 	 * audit record.
421 	 */
422 	if (tad->tad_ctrl & PAD_AUDITME)
423 		return (AU_OK);
424 
425 	/*
426 	 * Used passed cred if available, otherwise use cred from kernel thread
427 	 */
428 	if (cr == NULL)
429 		cr = CRED();
430 	ainfo = crgetauinfo(cr);
431 	if (ainfo == NULL)
432 		return (0);
433 	amask = ainfo->ai_mask;
434 
435 	if (error == 0)
436 		return ((ess & amask.as_success) ? AU_OK : 0);
437 	else
438 		return ((esf & amask.as_failure) ? AU_OK : 0);
439 }
440 
441 /*
442  * determine if we've preselected this event (system call).
443  */
444 int
445 auditme(au_kcontext_t *kctx, struct t_audit_data *tad, au_state_t estate)
446 {
447 	int flag = 0;
448 	au_mask_t amask;
449 	const auditinfo_addr_t *ainfo;
450 
451 	ainfo = crgetauinfo(CRED());
452 	if (ainfo == NULL)
453 		return (0);
454 	amask = ainfo->ai_mask;
455 
456 		/* preselected system call */
457 
458 	if (amask.as_success & estate || amask.as_failure & estate) {
459 		flag = 1;
460 	} else if ((tad->tad_scid == SYS_putmsg) ||
461 	    (tad->tad_scid == SYS_getmsg)) {
462 		estate = kctx->auk_ets[AUE_SOCKCONNECT]	|
463 		    kctx->auk_ets[AUE_SOCKACCEPT]	|
464 		    kctx->auk_ets[AUE_SOCKSEND]		|
465 		    kctx->auk_ets[AUE_SOCKRECEIVE];
466 		if (amask.as_success & estate || amask.as_failure & estate)
467 			flag = 1;
468 	}
469 
470 	return (flag);
471 }
472