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