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 5*45916cd2Sjpk * Common Development and Distribution License (the "License"). 6*45916cd2Sjpk * 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 /* 22*45916cd2Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * This file contains the envelope code for system call auditing. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <sys/param.h> 337c478bd9Sstevel@tonic-gate #include <sys/types.h> 347c478bd9Sstevel@tonic-gate #include <sys/time.h> 357c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 367c478bd9Sstevel@tonic-gate #include <sys/proc.h> 377c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 387c478bd9Sstevel@tonic-gate #include <sys/file.h> 397c478bd9Sstevel@tonic-gate #include <sys/user.h> 407c478bd9Sstevel@tonic-gate #include <sys/stropts.h> 417c478bd9Sstevel@tonic-gate #include <sys/systm.h> 427c478bd9Sstevel@tonic-gate #include <sys/pathname.h> 437c478bd9Sstevel@tonic-gate #include <sys/debug.h> 447c478bd9Sstevel@tonic-gate #include <sys/cred_impl.h> 457c478bd9Sstevel@tonic-gate #include <sys/zone.h> 46*45916cd2Sjpk #include <sys/tsol/label.h> 477c478bd9Sstevel@tonic-gate #include <c2/audit.h> 487c478bd9Sstevel@tonic-gate #include <c2/audit_kernel.h> 497c478bd9Sstevel@tonic-gate #include <c2/audit_kevents.h> 507c478bd9Sstevel@tonic-gate #include <c2/audit_record.h> 517c478bd9Sstevel@tonic-gate #include "audit_door_infc.h" 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate extern uint_t num_syscall; /* size of audit_s2e table */ 547c478bd9Sstevel@tonic-gate extern kmutex_t pidlock; /* proc table lock */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate int audit_load = 0; /* set from /etc/system */ 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate struct p_audit_data *pad0; 597c478bd9Sstevel@tonic-gate struct t_audit_data *tad0; 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate /* 627c478bd9Sstevel@tonic-gate * Das Boot. Initialize first process. Also generate an audit record indicating 637c478bd9Sstevel@tonic-gate * that the system has been booted. 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate void 667c478bd9Sstevel@tonic-gate audit_init() 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate kthread_t *au_thread; 697c478bd9Sstevel@tonic-gate token_t *rp = NULL; 707c478bd9Sstevel@tonic-gate label_t jb; 717c478bd9Sstevel@tonic-gate struct audit_path apempty; 727c478bd9Sstevel@tonic-gate auditinfo_addr_t *ainfo; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate if (audit_load == 0) { 757c478bd9Sstevel@tonic-gate audit_active = 0; 767c478bd9Sstevel@tonic-gate au_auditstate = AUC_DISABLED; 777c478bd9Sstevel@tonic-gate return; 787c478bd9Sstevel@tonic-gate #ifdef DEBUG 797c478bd9Sstevel@tonic-gate } else if (audit_load == 2) { 807c478bd9Sstevel@tonic-gate debug_enter((char *)NULL); 817c478bd9Sstevel@tonic-gate #endif 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate audit_active = 1; 857c478bd9Sstevel@tonic-gate set_all_proc_sys(); /* set pre- and post-syscall flags */ 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate /* initialize memory allocators */ 887c478bd9Sstevel@tonic-gate au_mem_init(); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate au_zone_setup(); 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate /* inital thread structure */ 937c478bd9Sstevel@tonic-gate tad0 = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP); 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* initial process structure */ 967c478bd9Sstevel@tonic-gate pad0 = kmem_cache_alloc(au_pad_cache, KM_SLEEP); 977c478bd9Sstevel@tonic-gate bzero(&pad0->pad_data, sizeof (pad0->pad_data)); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate T2A(curthread) = tad0; 1007c478bd9Sstevel@tonic-gate P2A(curproc) = pad0; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate /* 1037c478bd9Sstevel@tonic-gate * The kernel allocates a bunch of threads make sure they have 1047c478bd9Sstevel@tonic-gate * a valid tad 1057c478bd9Sstevel@tonic-gate */ 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate mutex_enter(&pidlock); 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate au_thread = curthread; 1107c478bd9Sstevel@tonic-gate do { 1117c478bd9Sstevel@tonic-gate if (T2A(au_thread) == NULL) { 1127c478bd9Sstevel@tonic-gate T2A(au_thread) = tad0; 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate au_thread = au_thread->t_next; 1157c478bd9Sstevel@tonic-gate } while (au_thread != curthread); 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate tad0->tad_ad = NULL; 1187c478bd9Sstevel@tonic-gate mutex_exit(&pidlock); 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate /* 1217c478bd9Sstevel@tonic-gate * Initialize audit context in our cred (kcred). 1227c478bd9Sstevel@tonic-gate * No copy-on-write needed here because it's so early in init. 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate ainfo = crgetauinfo_modifiable(kcred); 1257c478bd9Sstevel@tonic-gate ASSERT(ainfo != NULL); 1267c478bd9Sstevel@tonic-gate bzero(ainfo, sizeof (auditinfo_addr_t)); 1277c478bd9Sstevel@tonic-gate ainfo->ai_auid = AU_NOAUDITID; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* fabricate an empty audit_path to extend */ 1307c478bd9Sstevel@tonic-gate apempty.audp_cnt = 0; 1317c478bd9Sstevel@tonic-gate apempty.audp_sect[0] = (char *)(&apempty.audp_sect[1]); 1327c478bd9Sstevel@tonic-gate pad0->pad_root = au_pathdup(&apempty, 1, 2); 1337c478bd9Sstevel@tonic-gate bcopy("/", pad0->pad_root->audp_sect[0], 2); 1347c478bd9Sstevel@tonic-gate au_pathhold(pad0->pad_root); 1357c478bd9Sstevel@tonic-gate pad0->pad_cwd = pad0->pad_root; 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate /* 1387c478bd9Sstevel@tonic-gate * setup environment for asynchronous auditing. We can't use 1397c478bd9Sstevel@tonic-gate * audit_async_start() here since it assumes the audit system 1407c478bd9Sstevel@tonic-gate * has been started via auditd(1m). auditd sets the variable, 1417c478bd9Sstevel@tonic-gate * auk_auditstate, to indicate audit record generation should 1427c478bd9Sstevel@tonic-gate * commence. Here we want to always generate an audit record. 1437c478bd9Sstevel@tonic-gate */ 1447c478bd9Sstevel@tonic-gate if (setjmp(&jb)) { 1457c478bd9Sstevel@tonic-gate /* process audit policy (AUDIT_AHLT) for asynchronous events */ 1467c478bd9Sstevel@tonic-gate audit_async_drop((caddr_t *)(&rp), 0); 1477c478bd9Sstevel@tonic-gate return; 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate ASSERT(tad0->tad_errjmp == NULL); 1517c478bd9Sstevel@tonic-gate tad0->tad_errjmp = (void *)&jb; 1527c478bd9Sstevel@tonic-gate tad0->tad_ctrl |= PAD_ERRJMP; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /* generate a system-booted audit record */ 1557c478bd9Sstevel@tonic-gate au_write((caddr_t *)&rp, au_to_text("booting kernel")); 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate audit_async_finish((caddr_t *)&rp, AUE_SYSTEMBOOT, NULL); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate void 1617c478bd9Sstevel@tonic-gate audit_free() 1627c478bd9Sstevel@tonic-gate { 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate /* 1667c478bd9Sstevel@tonic-gate * Check for any pending changes to the audit context for the given proc. 1677c478bd9Sstevel@tonic-gate * p_crlock and pad_lock for the process are acquired here. Caller is 1687c478bd9Sstevel@tonic-gate * responsible for assuring the process doesn't go away. If context is 1697c478bd9Sstevel@tonic-gate * updated, the specified cralloc'ed cred will be used, otherwise it's freed. 1707c478bd9Sstevel@tonic-gate * If no cred is given, it will be cralloc'ed here and caller assures that 1717c478bd9Sstevel@tonic-gate * it is safe to allocate memory. 1727c478bd9Sstevel@tonic-gate */ 1737c478bd9Sstevel@tonic-gate void 1747c478bd9Sstevel@tonic-gate audit_update_context(proc_t *p, cred_t *ncr) 1757c478bd9Sstevel@tonic-gate { 1767c478bd9Sstevel@tonic-gate struct p_audit_data *pad; 1777c478bd9Sstevel@tonic-gate cred_t *newcred = ncr; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate pad = P2A(p); 1807c478bd9Sstevel@tonic-gate if (pad == NULL) { 1817c478bd9Sstevel@tonic-gate if (newcred != NULL) 1827c478bd9Sstevel@tonic-gate crfree(newcred); 1837c478bd9Sstevel@tonic-gate return; 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate /* If a mask update is pending, take care of it. */ 1877c478bd9Sstevel@tonic-gate if (pad->pad_flags & PAD_SETMASK) { 1887c478bd9Sstevel@tonic-gate auditinfo_addr_t *ainfo; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate if (newcred == NULL) 1917c478bd9Sstevel@tonic-gate newcred = cralloc(); 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate mutex_enter(&pad->pad_lock); 1947c478bd9Sstevel@tonic-gate /* the condition may have been handled by the time we lock */ 1957c478bd9Sstevel@tonic-gate if (pad->pad_flags & PAD_SETMASK) { 1967c478bd9Sstevel@tonic-gate ainfo = crgetauinfo_modifiable(newcred); 1977c478bd9Sstevel@tonic-gate if (ainfo == NULL) { 1987c478bd9Sstevel@tonic-gate mutex_enter(&pad->pad_lock); 1997c478bd9Sstevel@tonic-gate crfree(newcred); 2007c478bd9Sstevel@tonic-gate return; 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate mutex_enter(&p->p_crlock); 2047c478bd9Sstevel@tonic-gate crcopy_to(p->p_cred, newcred); 2057c478bd9Sstevel@tonic-gate p->p_cred = newcred; 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate ainfo->ai_mask = pad->pad_newmask; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* Unlock and cleanup. */ 2107c478bd9Sstevel@tonic-gate mutex_exit(&p->p_crlock); 2117c478bd9Sstevel@tonic-gate pad->pad_flags &= ~PAD_SETMASK; 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 2147c478bd9Sstevel@tonic-gate * For curproc, assure that our thread points to right 2157c478bd9Sstevel@tonic-gate * cred, so CRED() will be correct. Otherwise, no need 2167c478bd9Sstevel@tonic-gate * to broadcast changes (via set_proc_pre_sys), since 2177c478bd9Sstevel@tonic-gate * t_pre_sys is ALWAYS on when audit is enabled... due 2187c478bd9Sstevel@tonic-gate * to syscall auditing. 2197c478bd9Sstevel@tonic-gate */ 2207c478bd9Sstevel@tonic-gate if (p == curproc) 2217c478bd9Sstevel@tonic-gate crset(p, newcred); 2227c478bd9Sstevel@tonic-gate else 2237c478bd9Sstevel@tonic-gate crfree(newcred); 2247c478bd9Sstevel@tonic-gate } else { 2257c478bd9Sstevel@tonic-gate crfree(newcred); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate mutex_exit(&pad->pad_lock); 2287c478bd9Sstevel@tonic-gate } else { 2297c478bd9Sstevel@tonic-gate if (newcred != NULL) 2307c478bd9Sstevel@tonic-gate crfree(newcred); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate /* 2367c478bd9Sstevel@tonic-gate * Enter system call. Do any necessary setup here. allocate resouces, etc. 2377c478bd9Sstevel@tonic-gate */ 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate #include <sys/syscall.h> 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2437c478bd9Sstevel@tonic-gate int 2447c478bd9Sstevel@tonic-gate audit_start( 2457c478bd9Sstevel@tonic-gate unsigned type, 2467c478bd9Sstevel@tonic-gate unsigned scid, 2477c478bd9Sstevel@tonic-gate int error, 2487c478bd9Sstevel@tonic-gate klwp_t *lwp) 2497c478bd9Sstevel@tonic-gate { 2507c478bd9Sstevel@tonic-gate int ctrl; 2517c478bd9Sstevel@tonic-gate au_event_t event; 2527c478bd9Sstevel@tonic-gate au_state_t estate; 2537c478bd9Sstevel@tonic-gate struct t_audit_data *tad; 2547c478bd9Sstevel@tonic-gate au_kcontext_t *kctx; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate tad = U2A(u); 2577c478bd9Sstevel@tonic-gate ASSERT(tad != NULL); 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate if (error) { 2607c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0; 2617c478bd9Sstevel@tonic-gate tad->tad_flag = 0; 2627c478bd9Sstevel@tonic-gate return (0); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate audit_update_context(curproc, NULL); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * if this is an indirect system call then don't do anything. 2697c478bd9Sstevel@tonic-gate * audit_start will be called again from indir() in trap.c 2707c478bd9Sstevel@tonic-gate */ 2717c478bd9Sstevel@tonic-gate if (scid == 0) { 2727c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0; 2737c478bd9Sstevel@tonic-gate tad->tad_flag = 0; 2747c478bd9Sstevel@tonic-gate return (0); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate if (scid >= num_syscall) 2777c478bd9Sstevel@tonic-gate scid = 0; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate /* we can no longer ber guarantied a valid lwp_ap */ 2807c478bd9Sstevel@tonic-gate /* so we need to force it valid a lot of stuff needs it */ 2817c478bd9Sstevel@tonic-gate (void) save_syscall_args(); 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /* get control information */ 2847c478bd9Sstevel@tonic-gate ctrl = audit_s2e[scid].au_ctrl; 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* 2877c478bd9Sstevel@tonic-gate * We need to gather paths for certain system calls even if they are 2887c478bd9Sstevel@tonic-gate * not audited so that we can audit the various f* calls and be 2897c478bd9Sstevel@tonic-gate * sure to have a CWD and CAR. Thus we thus set tad_ctrl over the 2907c478bd9Sstevel@tonic-gate * system call regardless if the call is audited or not. 2917c478bd9Sstevel@tonic-gate * We allow the au_init() routine to adjust the tad_ctrl. 2927c478bd9Sstevel@tonic-gate */ 2937c478bd9Sstevel@tonic-gate tad->tad_ctrl = ctrl; 2947c478bd9Sstevel@tonic-gate tad->tad_scid = scid; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate /* get basic event for system call */ 2977c478bd9Sstevel@tonic-gate event = (*audit_s2e[scid].au_init)(audit_s2e[scid].au_event); 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate kctx = SET_KCTX_PZ; 3007c478bd9Sstevel@tonic-gate if (kctx == NULL) { 3017c478bd9Sstevel@tonic-gate zone_status_t zstate = zone_status_get(curproc->p_zone); 3027c478bd9Sstevel@tonic-gate ASSERT(zstate != ZONE_IS_READY); 3037c478bd9Sstevel@tonic-gate return (0); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[event]; 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* now do preselection. Audit or not to Audit, that is the question */ 3097c478bd9Sstevel@tonic-gate if ((tad->tad_flag = auditme(kctx, tad, estate)) == 0) { 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * we assume that audit_finish will always be called. 3127c478bd9Sstevel@tonic-gate */ 3137c478bd9Sstevel@tonic-gate return (0); 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate /* 3177c478bd9Sstevel@tonic-gate * if auditing not enabled, then don't generate an audit record 3187c478bd9Sstevel@tonic-gate * and don't count it. 3197c478bd9Sstevel@tonic-gate */ 3207c478bd9Sstevel@tonic-gate if ((kctx->auk_auditstate != AUC_AUDITING && 3217c478bd9Sstevel@tonic-gate kctx->auk_auditstate != AUC_INIT_AUDIT)) { 3227c478bd9Sstevel@tonic-gate /* 3237c478bd9Sstevel@tonic-gate * we assume that audit_finish will always be called. 3247c478bd9Sstevel@tonic-gate */ 3257c478bd9Sstevel@tonic-gate tad->tad_flag = 0; 3267c478bd9Sstevel@tonic-gate return (0); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate /* 3307c478bd9Sstevel@tonic-gate * audit daemon has informed us that there is no longer any 3317c478bd9Sstevel@tonic-gate * space left to hold audit records. We decide here if records 3327c478bd9Sstevel@tonic-gate * should be dropped (but counted). 3337c478bd9Sstevel@tonic-gate */ 3347c478bd9Sstevel@tonic-gate if (kctx->auk_auditstate == AUC_NOSPACE) { 3357c478bd9Sstevel@tonic-gate if ((kctx->auk_policy & AUDIT_CNT) || 3367c478bd9Sstevel@tonic-gate (kctx->auk_policy & AUDIT_SCNT)) { 3377c478bd9Sstevel@tonic-gate /* assume that audit_finish will always be called. */ 3387c478bd9Sstevel@tonic-gate tad->tad_flag = 0; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate /* just count # of dropped audit records */ 3417c478bd9Sstevel@tonic-gate AS_INC(as_dropped, 1, kctx); 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate return (0); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate } 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate tad->tad_event = event; 3487c478bd9Sstevel@tonic-gate tad->tad_evmod = 0; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate (*audit_s2e[scid].au_start)(tad); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate return (0); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate /* 3567c478bd9Sstevel@tonic-gate * system call has completed. Now determine if we genearate an audit record 3577c478bd9Sstevel@tonic-gate * or not. 3587c478bd9Sstevel@tonic-gate */ 3597c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3607c478bd9Sstevel@tonic-gate void 3617c478bd9Sstevel@tonic-gate audit_finish( 3627c478bd9Sstevel@tonic-gate unsigned type, 3637c478bd9Sstevel@tonic-gate unsigned scid, 3647c478bd9Sstevel@tonic-gate int error, 3657c478bd9Sstevel@tonic-gate rval_t *rval) 3667c478bd9Sstevel@tonic-gate { 3677c478bd9Sstevel@tonic-gate struct t_audit_data *tad; 3687c478bd9Sstevel@tonic-gate int flag; 3697c478bd9Sstevel@tonic-gate au_defer_info_t *attr; 3707c478bd9Sstevel@tonic-gate au_kcontext_t *kctx = SET_KCTX_PZ; 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate if (kctx == NULL) { 3737c478bd9Sstevel@tonic-gate zone_status_t zstate = zone_status_get(curproc->p_zone); 3747c478bd9Sstevel@tonic-gate ASSERT(zstate != ZONE_IS_READY); 3757c478bd9Sstevel@tonic-gate return; 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate tad = U2A(u); 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate /* 3817c478bd9Sstevel@tonic-gate * Process all deferred events first. 3827c478bd9Sstevel@tonic-gate */ 3837c478bd9Sstevel@tonic-gate attr = tad->tad_defer_head; 3847c478bd9Sstevel@tonic-gate while (attr != NULL) { 3857c478bd9Sstevel@tonic-gate au_defer_info_t *tmp_attr = attr; 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate au_close_time(kctx, (token_t *)attr->audi_ad, attr->audi_flag, 3887c478bd9Sstevel@tonic-gate attr->audi_e_type, attr->audi_e_mod, &(attr->audi_atime)); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate attr = attr->audi_next; 3917c478bd9Sstevel@tonic-gate kmem_free(tmp_attr, sizeof (au_defer_info_t)); 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate tad->tad_defer_head = tad->tad_defer_tail = NULL; 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate if (tad->tad_flag == 0 && !(tad->tad_ctrl & PAD_SAVPATH)) { 3967c478bd9Sstevel@tonic-gate /* 3977c478bd9Sstevel@tonic-gate * clear the ctrl flag so that we don't have spurious 3987c478bd9Sstevel@tonic-gate * collection of audit information. 3997c478bd9Sstevel@tonic-gate */ 4007c478bd9Sstevel@tonic-gate tad->tad_scid = 0; 4017c478bd9Sstevel@tonic-gate tad->tad_event = 0; 4027c478bd9Sstevel@tonic-gate tad->tad_evmod = 0; 4037c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0; 4047c478bd9Sstevel@tonic-gate ASSERT(tad->tad_aupath == NULL); 4057c478bd9Sstevel@tonic-gate return; 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate scid = tad->tad_scid; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate /* 4117c478bd9Sstevel@tonic-gate * Perform any extra processing and determine if we are 4127c478bd9Sstevel@tonic-gate * really going to generate any audit record. 4137c478bd9Sstevel@tonic-gate */ 4147c478bd9Sstevel@tonic-gate (*audit_s2e[scid].au_finish)(tad, error, rval); 4157c478bd9Sstevel@tonic-gate if (tad->tad_flag) { 4167c478bd9Sstevel@tonic-gate tad->tad_flag = 0; 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate if (flag = audit_success(kctx, tad, error)) { 4197c478bd9Sstevel@tonic-gate unsigned int sy_flags; 4207c478bd9Sstevel@tonic-gate cred_t *cr = CRED(); 4217c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo = crgetauinfo(cr); 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate ASSERT(ainfo != NULL); 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate /* Add a subject token */ 4267c478bd9Sstevel@tonic-gate AUDIT_SETSUBJ(&(u_ad), cr, ainfo); 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate /* Add an optional group token */ 4297c478bd9Sstevel@tonic-gate AUDIT_SETGROUP(&(u_ad), cr, kctx); 4307c478bd9Sstevel@tonic-gate 431*45916cd2Sjpk /* Add token for process SL */ 432*45916cd2Sjpk if (is_system_labeled()) 433*45916cd2Sjpk au_write(&(u_ad), au_to_label(CR_SL(cr))); 434*45916cd2Sjpk 4357c478bd9Sstevel@tonic-gate if (tad->tad_evmod & PAD_SPRIVUSE) 4367c478bd9Sstevel@tonic-gate au_write(&(u_ad), 4377c478bd9Sstevel@tonic-gate au_to_privset("", &tad->tad_sprivs, 4387c478bd9Sstevel@tonic-gate AUT_UPRIV, 1)); 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate if (tad->tad_evmod & PAD_FPRIVUSE) 4417c478bd9Sstevel@tonic-gate au_write(&(u_ad), 4427c478bd9Sstevel@tonic-gate au_to_privset("", &tad->tad_fprivs, 4437c478bd9Sstevel@tonic-gate AUT_UPRIV, 0)); 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate /* Add a return token */ 4467c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32_IMPL 4477c478bd9Sstevel@tonic-gate if (lwp_getdatamodel( 4487c478bd9Sstevel@tonic-gate ttolwp(curthread)) == DATAMODEL_NATIVE) 4497c478bd9Sstevel@tonic-gate sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK; 4507c478bd9Sstevel@tonic-gate else 4517c478bd9Sstevel@tonic-gate sy_flags = sysent32[scid].sy_flags & SE_RVAL_MASK; 4527c478bd9Sstevel@tonic-gate #else 4537c478bd9Sstevel@tonic-gate sy_flags = sysent[scid].sy_flags & SE_RVAL_MASK; 4547c478bd9Sstevel@tonic-gate #endif 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate if (sy_flags == SE_32RVAL1) { 4577c478bd9Sstevel@tonic-gate if (type == 0) { 4587c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_return32(error, 0)); 4597c478bd9Sstevel@tonic-gate } else { 4607c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_return32(error, 4617c478bd9Sstevel@tonic-gate rval->r_val1)); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate if (sy_flags == (SE_32RVAL2|SE_32RVAL1)) { 4657c478bd9Sstevel@tonic-gate if (type == 0) { 4667c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_return32(error, 0)); 4677c478bd9Sstevel@tonic-gate } else { 4687c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_return32(error, 4697c478bd9Sstevel@tonic-gate rval->r_val1)); 4707c478bd9Sstevel@tonic-gate #ifdef NOTYET /* for possible future support */ 4717c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_return32(error, 4727c478bd9Sstevel@tonic-gate rval->r_val2)); 4737c478bd9Sstevel@tonic-gate #endif 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate if (sy_flags == SE_64RVAL) { 4777c478bd9Sstevel@tonic-gate if (type == 0) { 4787c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_return64(error, 0)); 4797c478bd9Sstevel@tonic-gate } else { 4807c478bd9Sstevel@tonic-gate au_write(&(u_ad), au_to_return64(error, 4817c478bd9Sstevel@tonic-gate rval->r_vals)); 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate AS_INC(as_generated, 1, kctx); 4867c478bd9Sstevel@tonic-gate AS_INC(as_kernel, 1, kctx); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate /* Close up everything */ 4907c478bd9Sstevel@tonic-gate au_close(kctx, &(u_ad), flag, tad->tad_event, tad->tad_evmod); 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate ASSERT(u_ad == NULL); 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate /* free up any space remaining with the path's */ 4967c478bd9Sstevel@tonic-gate if (tad->tad_aupath != NULL) { 4977c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_aupath); 4987c478bd9Sstevel@tonic-gate tad->tad_aupath = NULL; 4997c478bd9Sstevel@tonic-gate tad->tad_vn = NULL; 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* free up any space remaining with openat path's */ 5037c478bd9Sstevel@tonic-gate if (tad->tad_atpath) { 5047c478bd9Sstevel@tonic-gate au_pathrele(tad->tad_atpath); 5057c478bd9Sstevel@tonic-gate tad->tad_atpath = NULL; 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate /* 5097c478bd9Sstevel@tonic-gate * clear the ctrl flag so that we don't have spurious collection of 5107c478bd9Sstevel@tonic-gate * audit information. 5117c478bd9Sstevel@tonic-gate */ 5127c478bd9Sstevel@tonic-gate tad->tad_scid = 0; 5137c478bd9Sstevel@tonic-gate tad->tad_event = 0; 5147c478bd9Sstevel@tonic-gate tad->tad_evmod = 0; 5157c478bd9Sstevel@tonic-gate tad->tad_ctrl = 0; 5167c478bd9Sstevel@tonic-gate } 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate int 5197c478bd9Sstevel@tonic-gate audit_success(au_kcontext_t *kctx, struct t_audit_data *tad, int error) 5207c478bd9Sstevel@tonic-gate { 5217c478bd9Sstevel@tonic-gate au_state_t ess; 5227c478bd9Sstevel@tonic-gate au_state_t esf; 5237c478bd9Sstevel@tonic-gate au_mask_t amask; 5247c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo; 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate ess = esf = kctx->auk_ets[tad->tad_event]; 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate if (error) 5297c478bd9Sstevel@tonic-gate tad->tad_evmod |= PAD_FAILURE; 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate /* see if we really want to generate an audit record */ 5327c478bd9Sstevel@tonic-gate if (tad->tad_ctrl & PAD_NOAUDIT) 5337c478bd9Sstevel@tonic-gate return (0); 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate /* 5367c478bd9Sstevel@tonic-gate * nfs operation and we're auditing privilege or MAC. This 5377c478bd9Sstevel@tonic-gate * is so we have a client audit record to match a nfs server 5387c478bd9Sstevel@tonic-gate * audit record. 5397c478bd9Sstevel@tonic-gate */ 5407c478bd9Sstevel@tonic-gate if (tad->tad_ctrl & PAD_AUDITME) 5417c478bd9Sstevel@tonic-gate return (AU_OK); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate ainfo = crgetauinfo(CRED()); 5447c478bd9Sstevel@tonic-gate if (ainfo == NULL) 5457c478bd9Sstevel@tonic-gate return (0); 5467c478bd9Sstevel@tonic-gate amask = ainfo->ai_mask; 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate if (error == 0) 5497c478bd9Sstevel@tonic-gate return ((ess & amask.as_success) ? AU_OK : 0); 5507c478bd9Sstevel@tonic-gate else 5517c478bd9Sstevel@tonic-gate return ((esf & amask.as_failure) ? AU_OK : 0); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* 5557c478bd9Sstevel@tonic-gate * determine if we've preselected this event (system call). 5567c478bd9Sstevel@tonic-gate */ 5577c478bd9Sstevel@tonic-gate int 5587c478bd9Sstevel@tonic-gate auditme(au_kcontext_t *kctx, struct t_audit_data *tad, au_state_t estate) 5597c478bd9Sstevel@tonic-gate { 5607c478bd9Sstevel@tonic-gate int flag = 0; 5617c478bd9Sstevel@tonic-gate au_mask_t amask; 5627c478bd9Sstevel@tonic-gate const auditinfo_addr_t *ainfo; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate ainfo = crgetauinfo(CRED()); 5657c478bd9Sstevel@tonic-gate if (ainfo == NULL) 5667c478bd9Sstevel@tonic-gate return (0); 5677c478bd9Sstevel@tonic-gate amask = ainfo->ai_mask; 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate /* preselected system call */ 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate if (amask.as_success & estate || amask.as_failure & estate) { 5727c478bd9Sstevel@tonic-gate flag = 1; 5737c478bd9Sstevel@tonic-gate } else if ((tad->tad_scid == SYS_putmsg) || 5747c478bd9Sstevel@tonic-gate (tad->tad_scid == SYS_getmsg)) { 5757c478bd9Sstevel@tonic-gate estate = kctx->auk_ets[AUE_SOCKCONNECT] | 5767c478bd9Sstevel@tonic-gate kctx->auk_ets[AUE_SOCKACCEPT] | 5777c478bd9Sstevel@tonic-gate kctx->auk_ets[AUE_SOCKSEND] | 5787c478bd9Sstevel@tonic-gate kctx->auk_ets[AUE_SOCKRECEIVE]; 5797c478bd9Sstevel@tonic-gate if (amask.as_success & estate || amask.as_failure & estate) 5807c478bd9Sstevel@tonic-gate flag = 1; 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate return (flag); 5847c478bd9Sstevel@tonic-gate } 585