xref: /illumos-gate/usr/src/uts/common/c2/audit_start.c (revision bbf21555)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
545916cd2Sjpk  * Common Development and Distribution License (the "License").
645916cd2Sjpk  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22134a1f4eSCasper H.S. Dik  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate  * This file contains the envelope code for system call auditing.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/param.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/time.h>
327c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
337c478bd9Sstevel@tonic-gate #include <sys/proc.h>
347c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
357c478bd9Sstevel@tonic-gate #include <sys/file.h>
367c478bd9Sstevel@tonic-gate #include <sys/user.h>
377c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
387c478bd9Sstevel@tonic-gate #include <sys/systm.h>
397c478bd9Sstevel@tonic-gate #include <sys/pathname.h>
407c478bd9Sstevel@tonic-gate #include <sys/debug.h>
4167dbe2beSCasper H.S. Dik #include <sys/cred.h>
427c478bd9Sstevel@tonic-gate #include <sys/zone.h>
437c478bd9Sstevel@tonic-gate #include <c2/audit.h>
447c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h>
457c478bd9Sstevel@tonic-gate #include <c2/audit_kevents.h>
467c478bd9Sstevel@tonic-gate #include <c2/audit_record.h>
477c478bd9Sstevel@tonic-gate #include "audit_door_infc.h"
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate extern uint_t num_syscall;		/* size of audit_s2e table */
507c478bd9Sstevel@tonic-gate extern kmutex_t pidlock;		/* proc table lock */
517c478bd9Sstevel@tonic-gate 
52005d3febSMarek Pospisil /*
53005d3febSMarek Pospisil  * Obsolete and ignored - Historically, the 'set c2audit:audit_load=1' entry
54005d3febSMarek Pospisil  * in /etc/system enabled auditing. The No Reboot Audit project does not
55005d3febSMarek Pospisil  * use this entry. However, to prevent the system from printing warning
56005d3febSMarek Pospisil  * messages, the audit_load entry is being left in /etc/system. It will be
57005d3febSMarek Pospisil  * removed when there is a small chance that the entry is used on currently
58005d3febSMarek Pospisil  * running systems.
59005d3febSMarek Pospisil  */
60005d3febSMarek Pospisil int audit_load = 0;
617c478bd9Sstevel@tonic-gate 
62005d3febSMarek Pospisil kmutex_t module_lock;			/* audit_module_state lock */
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate /*
657c478bd9Sstevel@tonic-gate  * Das Boot. Initialize first process. Also generate an audit record indicating
667c478bd9Sstevel@tonic-gate  * that the system has been booted.
677c478bd9Sstevel@tonic-gate  */
687c478bd9Sstevel@tonic-gate void
audit_init_module()69005d3febSMarek Pospisil audit_init_module()
707c478bd9Sstevel@tonic-gate {
717c478bd9Sstevel@tonic-gate 	token_t *rp = NULL;
727c478bd9Sstevel@tonic-gate 	label_t jb;
7360afd2f6SMarek Pospisil 	t_audit_data_t *tad = U2A(u);
747c478bd9Sstevel@tonic-gate 
75005d3febSMarek Pospisil 	/*
76005d3febSMarek Pospisil 	 * Solaris Auditing module is being loaded -> change the state. The lock
77005d3febSMarek Pospisil 	 * is here to prevent memory leaks caused by multiple initializations.
78005d3febSMarek Pospisil 	 */
79005d3febSMarek Pospisil 	mutex_enter(&module_lock);
80005d3febSMarek Pospisil 	if (audit_active != C2AUDIT_UNLOADED) {
81005d3febSMarek Pospisil 		mutex_exit(&module_lock);
827c478bd9Sstevel@tonic-gate 		return;
837c478bd9Sstevel@tonic-gate 	}
84005d3febSMarek Pospisil 	audit_active = C2AUDIT_LOADED;
85005d3febSMarek Pospisil 	mutex_exit(&module_lock);
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	/* initialize memory allocators */
887c478bd9Sstevel@tonic-gate 	au_mem_init();
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	/*
917c478bd9Sstevel@tonic-gate 	 * setup environment for asynchronous auditing. We can't use
927c478bd9Sstevel@tonic-gate 	 * audit_async_start() here since it assumes the audit system
93*bbf21555SRichard Lowe 	 * has been started via auditd(8). auditd sets the variable,
947c478bd9Sstevel@tonic-gate 	 * auk_auditstate, to indicate audit record generation should
957c478bd9Sstevel@tonic-gate 	 * commence. Here we want to always generate an audit record.
967c478bd9Sstevel@tonic-gate 	 */
977c478bd9Sstevel@tonic-gate 	if (setjmp(&jb)) {
987c478bd9Sstevel@tonic-gate 		/* process audit policy (AUDIT_AHLT) for asynchronous events */
997c478bd9Sstevel@tonic-gate 		audit_async_drop((caddr_t *)(&rp), 0);
1007c478bd9Sstevel@tonic-gate 		return;
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate 
10360afd2f6SMarek Pospisil 	ASSERT(tad->tad_errjmp == NULL);
10460afd2f6SMarek Pospisil 	tad->tad_errjmp = (void *)&jb;
1054a0fa546SMarek Pospisil 	tad->tad_ctrl |= TAD_ERRJMP;
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	/* generate a system-booted audit record */
1087c478bd9Sstevel@tonic-gate 	au_write((caddr_t *)&rp, au_to_text("booting kernel"));
1090f48f68dSToomas Soome 	audit_async_finish((caddr_t *)&rp, AUE_SYSTEMBOOT, 0,
110005d3febSMarek Pospisil 	    &(p0.p_user.u_start));
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate /*
1157c478bd9Sstevel@tonic-gate  * Enter system call. Do any necessary setup here. allocate resouces, etc.
1167c478bd9Sstevel@tonic-gate  */
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate #include <sys/syscall.h>
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1227c478bd9Sstevel@tonic-gate int
audit_start(unsigned type,unsigned scid,uint32_t audit_state,int error,klwp_t * lwp)1237c478bd9Sstevel@tonic-gate audit_start(
1247c478bd9Sstevel@tonic-gate 	unsigned type,
1257c478bd9Sstevel@tonic-gate 	unsigned scid,
126005d3febSMarek Pospisil 	uint32_t audit_state,
1277c478bd9Sstevel@tonic-gate 	int error,
1287c478bd9Sstevel@tonic-gate 	klwp_t *lwp)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate 	struct t_audit_data	*tad;
1317c478bd9Sstevel@tonic-gate 	au_kcontext_t		*kctx;
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	tad = U2A(u);
1347c478bd9Sstevel@tonic-gate 	ASSERT(tad != NULL);
1357c478bd9Sstevel@tonic-gate 
136005d3febSMarek Pospisil 	/* Remember the audit state in the cache */
137005d3febSMarek Pospisil 	tad->tad_audit = audit_state;
138005d3febSMarek Pospisil 
1397c478bd9Sstevel@tonic-gate 	if (error) {
1407c478bd9Sstevel@tonic-gate 		tad->tad_ctrl = 0;
1417c478bd9Sstevel@tonic-gate 		tad->tad_flag = 0;
1427c478bd9Sstevel@tonic-gate 		return (0);
1437c478bd9Sstevel@tonic-gate 	}
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	audit_update_context(curproc, NULL);
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	/*
1487c478bd9Sstevel@tonic-gate 	 * if this is an indirect system call then don't do anything.
1497c478bd9Sstevel@tonic-gate 	 * audit_start will be called again from indir() in trap.c
1507c478bd9Sstevel@tonic-gate 	 */
1517c478bd9Sstevel@tonic-gate 	if (scid == 0) {
1527c478bd9Sstevel@tonic-gate 		tad->tad_ctrl = 0;
1537c478bd9Sstevel@tonic-gate 		tad->tad_flag = 0;
1547c478bd9Sstevel@tonic-gate 		return (0);
1557c478bd9Sstevel@tonic-gate 	}
1567c478bd9Sstevel@tonic-gate 	if (scid >= num_syscall)
1577c478bd9Sstevel@tonic-gate 		scid = 0;
1587c478bd9Sstevel@tonic-gate 
159f9d0e028Sgww 	/*
160f9d0e028Sgww 	 * we can no longer depend on a valid lwp_ap, so we need to
161f9d0e028Sgww 	 * copy the syscall args as future audit stuff may need them.
162f9d0e028Sgww 	 */
1637c478bd9Sstevel@tonic-gate 	(void) save_syscall_args();
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	/*
1667c478bd9Sstevel@tonic-gate 	 * We need to gather paths for certain system calls even if they are
1677c478bd9Sstevel@tonic-gate 	 * not audited so that we can audit the various f* calls and be
1687c478bd9Sstevel@tonic-gate 	 * sure to have a CWD and CAR. Thus we thus set tad_ctrl over the
1697c478bd9Sstevel@tonic-gate 	 * system call regardless if the call is audited or not.
170f9d0e028Sgww 	 * We allow the event specific initial processing routines (au_init)
171f9d0e028Sgww 	 * to adjust the tad_ctrl as necessary.
1727c478bd9Sstevel@tonic-gate 	 */
173f9d0e028Sgww 	tad->tad_ctrl   = audit_s2e[scid].au_ctrl;
1747c478bd9Sstevel@tonic-gate 	tad->tad_scid   = scid;
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	/* get basic event for system call */
177f9d0e028Sgww 	tad->tad_event = audit_s2e[scid].au_event;
1789f7e0c70SToomas Soome 	if (audit_s2e[scid].au_init != (au_event_t (*)(au_event_t))NULL) {
179f9d0e028Sgww 		/* get specific event */
180f9d0e028Sgww 		tad->tad_event = (*audit_s2e[scid].au_init)(tad->tad_event);
181f9d0e028Sgww 	}
1827c478bd9Sstevel@tonic-gate 
1839e9e6ab8Spaulson 	kctx = GET_KCTX_PZ;
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	/* now do preselection. Audit or not to Audit, that is the question */
186f9d0e028Sgww 	if ((tad->tad_flag = auditme(kctx, tad,
187f9d0e028Sgww 	    kctx->auk_ets[tad->tad_event])) == 0) {
1887c478bd9Sstevel@tonic-gate 		/*
1897c478bd9Sstevel@tonic-gate 		 * we assume that audit_finish will always be called.
1907c478bd9Sstevel@tonic-gate 		 */
1917c478bd9Sstevel@tonic-gate 		return (0);
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	/*
1957c478bd9Sstevel@tonic-gate 	 * if auditing not enabled, then don't generate an audit record
1967c478bd9Sstevel@tonic-gate 	 * and don't count it.
1977c478bd9Sstevel@tonic-gate 	 */
198005d3febSMarek Pospisil 	if (audit_state & ~(AUC_AUDITING | AUC_INIT_AUDIT)) {
1997c478bd9Sstevel@tonic-gate 		/*
2007c478bd9Sstevel@tonic-gate 		 * we assume that audit_finish will always be called.
2017c478bd9Sstevel@tonic-gate 		 */
2027c478bd9Sstevel@tonic-gate 		tad->tad_flag = 0;
2037c478bd9Sstevel@tonic-gate 		return (0);
2047c478bd9Sstevel@tonic-gate 	}
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	/*
2077c478bd9Sstevel@tonic-gate 	 * audit daemon has informed us that there is no longer any
2087c478bd9Sstevel@tonic-gate 	 * space left to hold audit records. We decide here if records
2097c478bd9Sstevel@tonic-gate 	 * should be dropped (but counted).
2107c478bd9Sstevel@tonic-gate 	 */
211005d3febSMarek Pospisil 	if (audit_state == AUC_NOSPACE) {
2127c478bd9Sstevel@tonic-gate 		if ((kctx->auk_policy & AUDIT_CNT) ||
2137c478bd9Sstevel@tonic-gate 		    (kctx->auk_policy & AUDIT_SCNT)) {
2147c478bd9Sstevel@tonic-gate 			/* assume that audit_finish will always be called. */
2157c478bd9Sstevel@tonic-gate 			tad->tad_flag = 0;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 			/* just count # of dropped audit records */
2187c478bd9Sstevel@tonic-gate 			AS_INC(as_dropped, 1, kctx);
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 			return (0);
2217c478bd9Sstevel@tonic-gate 		}
2227c478bd9Sstevel@tonic-gate 	}
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	tad->tad_evmod  = 0;
2257c478bd9Sstevel@tonic-gate 
226f9d0e028Sgww 	if (audit_s2e[scid].au_start != NULL) {
227f9d0e028Sgww 		/* do start of system call processing */
228f9d0e028Sgww 		(*audit_s2e[scid].au_start)(tad);
229f9d0e028Sgww 	}
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	return (0);
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate /*
2357c478bd9Sstevel@tonic-gate  * system call has completed. Now determine if we genearate an audit record
2367c478bd9Sstevel@tonic-gate  * or not.
2377c478bd9Sstevel@tonic-gate  */
2387c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2397c478bd9Sstevel@tonic-gate void
audit_finish(unsigned type,unsigned scid,int error,rval_t * rval)2407c478bd9Sstevel@tonic-gate audit_finish(
2417c478bd9Sstevel@tonic-gate 	unsigned type,
2427c478bd9Sstevel@tonic-gate 	unsigned scid,
2437c478bd9Sstevel@tonic-gate 	int error,
2447c478bd9Sstevel@tonic-gate 	rval_t *rval)
2457c478bd9Sstevel@tonic-gate {
2467c478bd9Sstevel@tonic-gate 	struct t_audit_data *tad;
2477c478bd9Sstevel@tonic-gate 	int	flag;
2487c478bd9Sstevel@tonic-gate 	au_defer_info_t	*attr;
2499e9e6ab8Spaulson 	au_kcontext_t *kctx = GET_KCTX_PZ;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	tad = U2A(u);
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	/*
2547c478bd9Sstevel@tonic-gate 	 * Process all deferred events first.
2557c478bd9Sstevel@tonic-gate 	 */
2567c478bd9Sstevel@tonic-gate 	attr = tad->tad_defer_head;
2577c478bd9Sstevel@tonic-gate 	while (attr != NULL) {
2587c478bd9Sstevel@tonic-gate 		au_defer_info_t	*tmp_attr = attr;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 		au_close_time(kctx, (token_t *)attr->audi_ad, attr->audi_flag,
2617c478bd9Sstevel@tonic-gate 		    attr->audi_e_type, attr->audi_e_mod, &(attr->audi_atime));
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 		attr = attr->audi_next;
2647c478bd9Sstevel@tonic-gate 		kmem_free(tmp_attr, sizeof (au_defer_info_t));
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 	tad->tad_defer_head = tad->tad_defer_tail = NULL;
2677c478bd9Sstevel@tonic-gate 
2684a0fa546SMarek Pospisil 	if (tad->tad_flag == 0 && !(tad->tad_ctrl & TAD_SAVPATH)) {
2697c478bd9Sstevel@tonic-gate 		/*
2707c478bd9Sstevel@tonic-gate 		 * clear the ctrl flag so that we don't have spurious
2717c478bd9Sstevel@tonic-gate 		 * collection of audit information.
2727c478bd9Sstevel@tonic-gate 		 */
2737c478bd9Sstevel@tonic-gate 		tad->tad_scid  = 0;
2747c478bd9Sstevel@tonic-gate 		tad->tad_event = 0;
2757c478bd9Sstevel@tonic-gate 		tad->tad_evmod = 0;
2767c478bd9Sstevel@tonic-gate 		tad->tad_ctrl  = 0;
277005d3febSMarek Pospisil 		tad->tad_audit = AUC_UNSET;
2787c478bd9Sstevel@tonic-gate 		ASSERT(tad->tad_aupath == NULL);
2797c478bd9Sstevel@tonic-gate 		return;
2807c478bd9Sstevel@tonic-gate 	}
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	scid = tad->tad_scid;
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 	/*
2857c478bd9Sstevel@tonic-gate 	 * Perform any extra processing and determine if we are
2867c478bd9Sstevel@tonic-gate 	 * really going to generate any audit record.
2877c478bd9Sstevel@tonic-gate 	 */
288f9d0e028Sgww 	if (audit_s2e[scid].au_finish != NULL) {
289f9d0e028Sgww 		/* do any post system call processing */
290f9d0e028Sgww 		(*audit_s2e[scid].au_finish)(tad, error, rval);
291f9d0e028Sgww 	}
2927c478bd9Sstevel@tonic-gate 	if (tad->tad_flag) {
2937c478bd9Sstevel@tonic-gate 		tad->tad_flag = 0;
2947c478bd9Sstevel@tonic-gate 
295799bd290Spwernau 		if (flag = audit_success(kctx, tad, error, NULL)) {
2967c478bd9Sstevel@tonic-gate 			unsigned int sy_flags;
2977c478bd9Sstevel@tonic-gate 			cred_t *cr = CRED();
2987c478bd9Sstevel@tonic-gate 			const auditinfo_addr_t *ainfo = crgetauinfo(cr);
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 			ASSERT(ainfo != NULL);
3017c478bd9Sstevel@tonic-gate 
30281490fd2Sgww 			/* Add subject information */
30381490fd2Sgww 			AUDIT_SETSUBJ(&(u_ad), cr, ainfo, kctx);
30445916cd2Sjpk 
305f9d0e028Sgww 			if (tad->tad_evmod & PAD_SPRIVUSE) {
3067c478bd9Sstevel@tonic-gate 				au_write(&(u_ad),
307f9d0e028Sgww 				    au_to_privset("", &tad->tad_sprivs,
308f9d0e028Sgww 				    AUT_UPRIV, 1));
309f9d0e028Sgww 			}
3107c478bd9Sstevel@tonic-gate 
311f9d0e028Sgww 			if (tad->tad_evmod & PAD_FPRIVUSE) {
3127c478bd9Sstevel@tonic-gate 				au_write(&(u_ad),
313f9d0e028Sgww 				    au_to_privset("", &tad->tad_fprivs,
314f9d0e028Sgww 				    AUT_UPRIV, 0));
315f9d0e028Sgww 			}
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate 			/* Add a return token */
318f9d0e028Sgww #ifdef	_SYSCALL32_IMPL
319f9d0e028Sgww 			if (lwp_getdatamodel(ttolwp(curthread)) ==
320f9d0e028Sgww 			    DATAMODEL_NATIVE) {
321f9d0e028Sgww 				sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
322f9d0e028Sgww 			} else {
323f9d0e028Sgww 				sy_flags =
324f9d0e028Sgww 				    sysent32[scid].sy_flags & SE_RVAL_MASK;
325f9d0e028Sgww 			}
326f9d0e028Sgww #else	/* _SYSCALL64_IMPL */
3277c478bd9Sstevel@tonic-gate 			sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK;
328f9d0e028Sgww #endif   /* _SYSCALL32_IMPL */
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 			if (sy_flags == SE_32RVAL1) {
331f9d0e028Sgww 				if (type == 0) {
332f9d0e028Sgww 					au_write(&(u_ad),
333f9d0e028Sgww 					    au_to_return32(error, 0));
334f9d0e028Sgww 				} else {
335f9d0e028Sgww 					au_write(&(u_ad), au_to_return32(error,
336f9d0e028Sgww 					    rval->r_val1));
337f9d0e028Sgww 				}
3387c478bd9Sstevel@tonic-gate 			}
3397c478bd9Sstevel@tonic-gate 			if (sy_flags == (SE_32RVAL2|SE_32RVAL1)) {
340f9d0e028Sgww 				if (type == 0) {
341f9d0e028Sgww 					au_write(&(u_ad),
342f9d0e028Sgww 					    au_to_return32(error, 0));
343f9d0e028Sgww 				} else {
344f9d0e028Sgww 					au_write(&(u_ad),
345f9d0e028Sgww 					    au_to_return32(error,
346f9d0e028Sgww 					    rval->r_val1));
3477c478bd9Sstevel@tonic-gate #ifdef NOTYET	/* for possible future support */
348f9d0e028Sgww 					au_write(&(u_ad), au_to_return32(error,
349f9d0e028Sgww 					    rval->r_val2));
3507c478bd9Sstevel@tonic-gate #endif
351f9d0e028Sgww 				}
3527c478bd9Sstevel@tonic-gate 			}
3537c478bd9Sstevel@tonic-gate 			if (sy_flags == SE_64RVAL) {
354f9d0e028Sgww 				if (type == 0) {
355f9d0e028Sgww 					au_write(&(u_ad),
356f9d0e028Sgww 					    au_to_return64(error, 0));
357f9d0e028Sgww 				} else {
358f9d0e028Sgww 					au_write(&(u_ad), au_to_return64(error,
359f9d0e028Sgww 					    rval->r_vals));
360f9d0e028Sgww 				}
3617c478bd9Sstevel@tonic-gate 			}
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 			AS_INC(as_generated, 1, kctx);
3647c478bd9Sstevel@tonic-gate 			AS_INC(as_kernel, 1, kctx);
3657c478bd9Sstevel@tonic-gate 		}
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 		/* Close up everything */
368005d3febSMarek Pospisil 		au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod,
369005d3febSMarek Pospisil 		    NULL);
3707c478bd9Sstevel@tonic-gate 	}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	ASSERT(u_ad == NULL);
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 	/* free up any space remaining with the path's */
3757c478bd9Sstevel@tonic-gate 	if (tad->tad_aupath != NULL) {
3767c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_aupath);
3777c478bd9Sstevel@tonic-gate 		tad->tad_aupath = NULL;
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 	/* free up any space remaining with openat path's */
3817c478bd9Sstevel@tonic-gate 	if (tad->tad_atpath) {
3827c478bd9Sstevel@tonic-gate 		au_pathrele(tad->tad_atpath);
3837c478bd9Sstevel@tonic-gate 		tad->tad_atpath = NULL;
3847c478bd9Sstevel@tonic-gate 	}
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 	/*
3877c478bd9Sstevel@tonic-gate 	 * clear the ctrl flag so that we don't have spurious collection of
3887c478bd9Sstevel@tonic-gate 	 * audit information.
3897c478bd9Sstevel@tonic-gate 	 */
3907c478bd9Sstevel@tonic-gate 	tad->tad_scid  = 0;
3917c478bd9Sstevel@tonic-gate 	tad->tad_event = 0;
3927c478bd9Sstevel@tonic-gate 	tad->tad_evmod = 0;
3937c478bd9Sstevel@tonic-gate 	tad->tad_ctrl  = 0;
394005d3febSMarek Pospisil 	tad->tad_audit = AUC_UNSET;
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate int
audit_success(au_kcontext_t * kctx,struct t_audit_data * tad,int error,cred_t * cr)398799bd290Spwernau audit_success(au_kcontext_t *kctx, struct t_audit_data *tad, int error,
399799bd290Spwernau     cred_t *cr)
4007c478bd9Sstevel@tonic-gate {
4017c478bd9Sstevel@tonic-gate 	au_state_t ess;
4027c478bd9Sstevel@tonic-gate 	au_state_t esf;
4037c478bd9Sstevel@tonic-gate 	au_mask_t amask;
4047c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 	ess = esf = kctx->auk_ets[tad->tad_event];
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	if (error)
4097c478bd9Sstevel@tonic-gate 		tad->tad_evmod |= PAD_FAILURE;
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	/* see if we really want to generate an audit record */
4124a0fa546SMarek Pospisil 	if (tad->tad_ctrl & TAD_NOAUDIT)
4137c478bd9Sstevel@tonic-gate 		return (0);
4147c478bd9Sstevel@tonic-gate 
415799bd290Spwernau 	/*
416799bd290Spwernau 	 * Used passed cred if available, otherwise use cred from kernel thread
417799bd290Spwernau 	 */
418799bd290Spwernau 	if (cr == NULL)
419799bd290Spwernau 		cr = CRED();
420799bd290Spwernau 	ainfo = crgetauinfo(cr);
4217c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
4227c478bd9Sstevel@tonic-gate 		return (0);
4237c478bd9Sstevel@tonic-gate 	amask = ainfo->ai_mask;
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	if (error == 0)
4267c478bd9Sstevel@tonic-gate 		return ((ess & amask.as_success) ? AU_OK : 0);
4277c478bd9Sstevel@tonic-gate 	else
4287c478bd9Sstevel@tonic-gate 		return ((esf & amask.as_failure) ? AU_OK : 0);
4297c478bd9Sstevel@tonic-gate }
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate /*
4327c478bd9Sstevel@tonic-gate  * determine if we've preselected this event (system call).
4337c478bd9Sstevel@tonic-gate  */
4347c478bd9Sstevel@tonic-gate int
auditme(au_kcontext_t * kctx,struct t_audit_data * tad,au_state_t estate)4357c478bd9Sstevel@tonic-gate auditme(au_kcontext_t *kctx, struct t_audit_data *tad, au_state_t estate)
4367c478bd9Sstevel@tonic-gate {
4377c478bd9Sstevel@tonic-gate 	int flag = 0;
4387c478bd9Sstevel@tonic-gate 	au_mask_t amask;
4397c478bd9Sstevel@tonic-gate 	const auditinfo_addr_t *ainfo;
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 	ainfo = crgetauinfo(CRED());
4427c478bd9Sstevel@tonic-gate 	if (ainfo == NULL)
4437c478bd9Sstevel@tonic-gate 		return (0);
4447c478bd9Sstevel@tonic-gate 	amask = ainfo->ai_mask;
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 		/* preselected system call */
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	if (amask.as_success & estate || amask.as_failure & estate) {
4497c478bd9Sstevel@tonic-gate 		flag = 1;
4507c478bd9Sstevel@tonic-gate 	} else if ((tad->tad_scid == SYS_putmsg) ||
451f9d0e028Sgww 	    (tad->tad_scid == SYS_getmsg)) {
4527c478bd9Sstevel@tonic-gate 		estate = kctx->auk_ets[AUE_SOCKCONNECT]	|
453f9d0e028Sgww 		    kctx->auk_ets[AUE_SOCKACCEPT]	|
454f9d0e028Sgww 		    kctx->auk_ets[AUE_SOCKSEND]		|
455f9d0e028Sgww 		    kctx->auk_ets[AUE_SOCKRECEIVE];
4567c478bd9Sstevel@tonic-gate 		if (amask.as_success & estate || amask.as_failure & estate)
4577c478bd9Sstevel@tonic-gate 			flag = 1;
458134a1f4eSCasper H.S. Dik 	} else if (tad->tad_scid == SYS_execve &&
459134a1f4eSCasper H.S. Dik 	    getpflags(PRIV_PFEXEC, CRED()) != 0) {
460134a1f4eSCasper H.S. Dik 		estate = kctx->auk_ets[AUE_PFEXEC];
461134a1f4eSCasper H.S. Dik 		if (amask.as_success & estate || amask.as_failure & estate)
462134a1f4eSCasper H.S. Dik 			flag = 1;
4637c478bd9Sstevel@tonic-gate 	}
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	return (flag);
4667c478bd9Sstevel@tonic-gate }
467