111861SMarek.Pospisil@Sun.COM /*
211861SMarek.Pospisil@Sun.COM * CDDL HEADER START
311861SMarek.Pospisil@Sun.COM *
411861SMarek.Pospisil@Sun.COM * The contents of this file are subject to the terms of the
511861SMarek.Pospisil@Sun.COM * Common Development and Distribution License (the "License").
611861SMarek.Pospisil@Sun.COM * You may not use this file except in compliance with the License.
711861SMarek.Pospisil@Sun.COM *
811861SMarek.Pospisil@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911861SMarek.Pospisil@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011861SMarek.Pospisil@Sun.COM * See the License for the specific language governing permissions
1111861SMarek.Pospisil@Sun.COM * and limitations under the License.
1211861SMarek.Pospisil@Sun.COM *
1311861SMarek.Pospisil@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411861SMarek.Pospisil@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511861SMarek.Pospisil@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611861SMarek.Pospisil@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711861SMarek.Pospisil@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811861SMarek.Pospisil@Sun.COM *
1911861SMarek.Pospisil@Sun.COM * CDDL HEADER END
2011861SMarek.Pospisil@Sun.COM */
2111861SMarek.Pospisil@Sun.COM /*
22*13126SMarek.Pospisil@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2311861SMarek.Pospisil@Sun.COM */
2411861SMarek.Pospisil@Sun.COM
2511861SMarek.Pospisil@Sun.COM #include <sys/param.h>
2611861SMarek.Pospisil@Sun.COM #include <sys/types.h>
2711861SMarek.Pospisil@Sun.COM #include <sys/time.h>
2811861SMarek.Pospisil@Sun.COM #include <sys/kmem.h>
2911861SMarek.Pospisil@Sun.COM #include <sys/proc.h>
3011861SMarek.Pospisil@Sun.COM #include <sys/vnode.h>
3111861SMarek.Pospisil@Sun.COM #include <sys/file.h>
3211861SMarek.Pospisil@Sun.COM #include <sys/user.h>
3311861SMarek.Pospisil@Sun.COM #include <sys/stropts.h>
3411861SMarek.Pospisil@Sun.COM #include <sys/systm.h>
3511861SMarek.Pospisil@Sun.COM #include <sys/pathname.h>
3611861SMarek.Pospisil@Sun.COM #include <sys/debug.h>
3711861SMarek.Pospisil@Sun.COM #include <sys/cred_impl.h>
3811861SMarek.Pospisil@Sun.COM #include <sys/zone.h>
3911861SMarek.Pospisil@Sun.COM #include <sys/modctl.h>
4011861SMarek.Pospisil@Sun.COM #include <sys/sysconf.h>
4111861SMarek.Pospisil@Sun.COM #include <c2/audit.h>
4211861SMarek.Pospisil@Sun.COM #include <c2/audit_kernel.h>
4311861SMarek.Pospisil@Sun.COM #include <c2/audit_kevents.h>
4411861SMarek.Pospisil@Sun.COM #include <c2/audit_record.h>
4511861SMarek.Pospisil@Sun.COM
4611861SMarek.Pospisil@Sun.COM
4711861SMarek.Pospisil@Sun.COM struct p_audit_data *pad0;
4811861SMarek.Pospisil@Sun.COM struct t_audit_data *tad0;
4911861SMarek.Pospisil@Sun.COM
5011861SMarek.Pospisil@Sun.COM extern uint_t num_syscall; /* size of audit_s2e table */
5111861SMarek.Pospisil@Sun.COM extern kmutex_t pidlock; /* proc table lock */
5211861SMarek.Pospisil@Sun.COM
5311861SMarek.Pospisil@Sun.COM
5411861SMarek.Pospisil@Sun.COM void
audit_init()5511861SMarek.Pospisil@Sun.COM audit_init()
5611861SMarek.Pospisil@Sun.COM {
5711861SMarek.Pospisil@Sun.COM kthread_t *au_thread;
5811861SMarek.Pospisil@Sun.COM auditinfo_addr_t *ainfo;
5911861SMarek.Pospisil@Sun.COM struct audit_path apempty;
6011861SMarek.Pospisil@Sun.COM
6111861SMarek.Pospisil@Sun.COM /*
6211861SMarek.Pospisil@Sun.COM * If the c2audit module is explicitely excluded in /etc/system,
6311861SMarek.Pospisil@Sun.COM * it cannot be loaded later (e.g. using modload). Make a notice
6411861SMarek.Pospisil@Sun.COM * that the module won't be present and do nothing.
6511861SMarek.Pospisil@Sun.COM */
6611861SMarek.Pospisil@Sun.COM
6711861SMarek.Pospisil@Sun.COM if (mod_sysctl(SYS_CHECK_EXCLUDE, "c2audit") != 0) {
6811861SMarek.Pospisil@Sun.COM audit_active = C2AUDIT_DISABLED;
6911861SMarek.Pospisil@Sun.COM return;
7011861SMarek.Pospisil@Sun.COM }
7111861SMarek.Pospisil@Sun.COM
7211861SMarek.Pospisil@Sun.COM /* c2audit module can be loaded anytime */
7311861SMarek.Pospisil@Sun.COM audit_active = C2AUDIT_UNLOADED;
7411861SMarek.Pospisil@Sun.COM
7511861SMarek.Pospisil@Sun.COM /* initialize the process audit data (pad) memory allocator */
7611861SMarek.Pospisil@Sun.COM au_pad_init();
7711861SMarek.Pospisil@Sun.COM
7811861SMarek.Pospisil@Sun.COM /* initialize the zone audit context */
7911861SMarek.Pospisil@Sun.COM au_zone_setup();
8011861SMarek.Pospisil@Sun.COM
8111861SMarek.Pospisil@Sun.COM /* inital thread structure */
8211861SMarek.Pospisil@Sun.COM tad0 = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
8311861SMarek.Pospisil@Sun.COM
8411861SMarek.Pospisil@Sun.COM /* initial process structure */
8511861SMarek.Pospisil@Sun.COM pad0 = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
8611861SMarek.Pospisil@Sun.COM bzero(&pad0->pad_data, sizeof (pad0->pad_data));
8711861SMarek.Pospisil@Sun.COM
8811861SMarek.Pospisil@Sun.COM curthread->t_audit_data = tad0;
8911861SMarek.Pospisil@Sun.COM curproc->p_audit_data = pad0;
9011861SMarek.Pospisil@Sun.COM
9111861SMarek.Pospisil@Sun.COM /*
9211861SMarek.Pospisil@Sun.COM * The kernel allocates a bunch of threads make sure they have
9311861SMarek.Pospisil@Sun.COM * a valid tad
9411861SMarek.Pospisil@Sun.COM */
9511861SMarek.Pospisil@Sun.COM
9611861SMarek.Pospisil@Sun.COM mutex_enter(&pidlock);
9711861SMarek.Pospisil@Sun.COM
9811861SMarek.Pospisil@Sun.COM au_thread = curthread;
9911861SMarek.Pospisil@Sun.COM do {
10011861SMarek.Pospisil@Sun.COM if (T2A(au_thread) == NULL) {
10111861SMarek.Pospisil@Sun.COM T2A(au_thread) = tad0;
10211861SMarek.Pospisil@Sun.COM }
10311861SMarek.Pospisil@Sun.COM au_thread = au_thread->t_next;
10411861SMarek.Pospisil@Sun.COM } while (au_thread != curthread);
10511861SMarek.Pospisil@Sun.COM
10611861SMarek.Pospisil@Sun.COM tad0->tad_ad = NULL;
10711861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
10811861SMarek.Pospisil@Sun.COM
10911861SMarek.Pospisil@Sun.COM /*
11011861SMarek.Pospisil@Sun.COM * Initialize audit context in our cred (kcred).
11111861SMarek.Pospisil@Sun.COM * No copy-on-write needed here because it's so early in init.
11211861SMarek.Pospisil@Sun.COM */
11311861SMarek.Pospisil@Sun.COM
11411861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo_modifiable(kcred);
11511861SMarek.Pospisil@Sun.COM ASSERT(ainfo != NULL);
11611861SMarek.Pospisil@Sun.COM bzero(ainfo, sizeof (auditinfo_addr_t));
11711861SMarek.Pospisil@Sun.COM ainfo->ai_auid = AU_NOAUDITID;
11811861SMarek.Pospisil@Sun.COM
11911861SMarek.Pospisil@Sun.COM /* fabricate an empty audit_path to extend */
12011861SMarek.Pospisil@Sun.COM apempty.audp_cnt = 0;
12111861SMarek.Pospisil@Sun.COM apempty.audp_sect[0] = (char *)(&apempty.audp_sect[1]);
12211861SMarek.Pospisil@Sun.COM pad0->pad_root = au_pathdup(&apempty, 1, 2);
12311861SMarek.Pospisil@Sun.COM bcopy("/", pad0->pad_root->audp_sect[0], 2);
12411861SMarek.Pospisil@Sun.COM au_pathhold(pad0->pad_root);
12511861SMarek.Pospisil@Sun.COM pad0->pad_cwd = pad0->pad_root;
12611861SMarek.Pospisil@Sun.COM }
12711861SMarek.Pospisil@Sun.COM
12811861SMarek.Pospisil@Sun.COM /*
12911861SMarek.Pospisil@Sun.COM * Check for any pending changes to the audit context for the given proc.
13011861SMarek.Pospisil@Sun.COM * p_crlock and pad_lock for the process are acquired here. Caller is
13111861SMarek.Pospisil@Sun.COM * responsible for assuring the process doesn't go away. If context is
13211861SMarek.Pospisil@Sun.COM * updated, the specified cralloc'ed cred will be used, otherwise it's freed.
13311861SMarek.Pospisil@Sun.COM * If no cred is given, it will be cralloc'ed here and caller assures that
13411861SMarek.Pospisil@Sun.COM * it is safe to allocate memory.
13511861SMarek.Pospisil@Sun.COM */
13611861SMarek.Pospisil@Sun.COM
13711861SMarek.Pospisil@Sun.COM void
audit_update_context(proc_t * p,cred_t * ncr)13811861SMarek.Pospisil@Sun.COM audit_update_context(proc_t *p, cred_t *ncr)
13911861SMarek.Pospisil@Sun.COM {
14011861SMarek.Pospisil@Sun.COM struct p_audit_data *pad;
14111861SMarek.Pospisil@Sun.COM cred_t *newcred = ncr;
14211861SMarek.Pospisil@Sun.COM
14311861SMarek.Pospisil@Sun.COM pad = P2A(p);
14411861SMarek.Pospisil@Sun.COM if (pad == NULL) {
14511861SMarek.Pospisil@Sun.COM if (newcred != NULL)
14611861SMarek.Pospisil@Sun.COM crfree(newcred);
14711861SMarek.Pospisil@Sun.COM return;
14811861SMarek.Pospisil@Sun.COM }
14911861SMarek.Pospisil@Sun.COM
15011861SMarek.Pospisil@Sun.COM /* If a mask update is pending, take care of it. */
15111861SMarek.Pospisil@Sun.COM if (pad->pad_flags & PAD_SETMASK) {
15211861SMarek.Pospisil@Sun.COM auditinfo_addr_t *ainfo;
15311861SMarek.Pospisil@Sun.COM
15411861SMarek.Pospisil@Sun.COM if (newcred == NULL)
15511861SMarek.Pospisil@Sun.COM newcred = cralloc();
15611861SMarek.Pospisil@Sun.COM
15711861SMarek.Pospisil@Sun.COM mutex_enter(&pad->pad_lock);
15811861SMarek.Pospisil@Sun.COM /* the condition may have been handled by the time we lock */
15911861SMarek.Pospisil@Sun.COM if (pad->pad_flags & PAD_SETMASK) {
16011861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo_modifiable(newcred);
16111861SMarek.Pospisil@Sun.COM if (ainfo == NULL) {
162*13126SMarek.Pospisil@Sun.COM mutex_exit(&pad->pad_lock);
16311861SMarek.Pospisil@Sun.COM crfree(newcred);
16411861SMarek.Pospisil@Sun.COM return;
16511861SMarek.Pospisil@Sun.COM }
16611861SMarek.Pospisil@Sun.COM
16711861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_crlock);
16811861SMarek.Pospisil@Sun.COM crcopy_to(p->p_cred, newcred);
16911861SMarek.Pospisil@Sun.COM p->p_cred = newcred;
17011861SMarek.Pospisil@Sun.COM
17111861SMarek.Pospisil@Sun.COM ainfo->ai_mask = pad->pad_newmask;
17211861SMarek.Pospisil@Sun.COM
17311861SMarek.Pospisil@Sun.COM /* Unlock and cleanup. */
17411861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_crlock);
17511861SMarek.Pospisil@Sun.COM pad->pad_flags &= ~PAD_SETMASK;
17611861SMarek.Pospisil@Sun.COM
17711861SMarek.Pospisil@Sun.COM /*
17811861SMarek.Pospisil@Sun.COM * For curproc, assure that our thread points to right
17911861SMarek.Pospisil@Sun.COM * cred, so CRED() will be correct. Otherwise, no need
18011861SMarek.Pospisil@Sun.COM * to broadcast changes (via set_proc_pre_sys), since
18111861SMarek.Pospisil@Sun.COM * t_pre_sys is ALWAYS on when audit is enabled... due
18211861SMarek.Pospisil@Sun.COM * to syscall auditing.
18311861SMarek.Pospisil@Sun.COM */
18411861SMarek.Pospisil@Sun.COM if (p == curproc)
18511861SMarek.Pospisil@Sun.COM crset(p, newcred);
18611861SMarek.Pospisil@Sun.COM else
18711861SMarek.Pospisil@Sun.COM crfree(newcred);
18811861SMarek.Pospisil@Sun.COM } else {
18911861SMarek.Pospisil@Sun.COM crfree(newcred);
19011861SMarek.Pospisil@Sun.COM }
19111861SMarek.Pospisil@Sun.COM mutex_exit(&pad->pad_lock);
19211861SMarek.Pospisil@Sun.COM } else {
19311861SMarek.Pospisil@Sun.COM if (newcred != NULL)
19411861SMarek.Pospisil@Sun.COM crfree(newcred);
19511861SMarek.Pospisil@Sun.COM }
19611861SMarek.Pospisil@Sun.COM }
19711861SMarek.Pospisil@Sun.COM
19811861SMarek.Pospisil@Sun.COM /*
19911861SMarek.Pospisil@Sun.COM * ROUTINE: AUDIT_NEWPROC
20011861SMarek.Pospisil@Sun.COM * PURPOSE: initialize the child p_audit_data structure
20111861SMarek.Pospisil@Sun.COM * CALLBY: GETPROC
20211861SMarek.Pospisil@Sun.COM * NOTE: All threads for the parent process are locked at this point.
20311861SMarek.Pospisil@Sun.COM * We are essentially running singled threaded for this reason.
20411861SMarek.Pospisil@Sun.COM * GETPROC is called when system creates a new process.
20511861SMarek.Pospisil@Sun.COM * By the time AUDIT_NEWPROC is called, the child proc
20611861SMarek.Pospisil@Sun.COM * structure has already been initialized. What we need
20711861SMarek.Pospisil@Sun.COM * to do is to allocate the child p_audit_data and
20811861SMarek.Pospisil@Sun.COM * initialize it with the content of current parent process.
20911861SMarek.Pospisil@Sun.COM */
21011861SMarek.Pospisil@Sun.COM
21111861SMarek.Pospisil@Sun.COM void
audit_newproc(struct proc * cp)21211861SMarek.Pospisil@Sun.COM audit_newproc(struct proc *cp) /* initialized child proc structure */
21311861SMarek.Pospisil@Sun.COM {
21411861SMarek.Pospisil@Sun.COM p_audit_data_t *pad; /* child process audit data */
21511861SMarek.Pospisil@Sun.COM p_audit_data_t *opad; /* parent process audit data */
21611861SMarek.Pospisil@Sun.COM
21711861SMarek.Pospisil@Sun.COM pad = kmem_cache_alloc(au_pad_cache, KM_SLEEP);
21811861SMarek.Pospisil@Sun.COM
21911861SMarek.Pospisil@Sun.COM P2A(cp) = pad;
22011861SMarek.Pospisil@Sun.COM
22111861SMarek.Pospisil@Sun.COM opad = P2A(curproc);
22211861SMarek.Pospisil@Sun.COM
22311861SMarek.Pospisil@Sun.COM /*
22411861SMarek.Pospisil@Sun.COM * copy the audit data. Note that all threads of current
22511861SMarek.Pospisil@Sun.COM * process have been "held". Thus there is no race condition
22611861SMarek.Pospisil@Sun.COM * here with mutiple threads trying to alter the cwrd
22711861SMarek.Pospisil@Sun.COM * structure (such as releasing it).
22811861SMarek.Pospisil@Sun.COM *
22911861SMarek.Pospisil@Sun.COM * The audit context in the cred is "duplicated" for the new
23011861SMarek.Pospisil@Sun.COM * proc by elsewhere crhold'ing the parent's cred which it shares.
23111861SMarek.Pospisil@Sun.COM *
23211861SMarek.Pospisil@Sun.COM * We still want to hold things since auditon() [A_SETUMASK,
23311861SMarek.Pospisil@Sun.COM * A_SETSMASK] could be walking through the processes to
23411861SMarek.Pospisil@Sun.COM * update things.
23511861SMarek.Pospisil@Sun.COM */
23611861SMarek.Pospisil@Sun.COM mutex_enter(&opad->pad_lock); /* lock opad structure during copy */
23711861SMarek.Pospisil@Sun.COM pad->pad_data = opad->pad_data; /* copy parent's process audit data */
23811861SMarek.Pospisil@Sun.COM au_pathhold(pad->pad_root);
23911861SMarek.Pospisil@Sun.COM au_pathhold(pad->pad_cwd);
24011861SMarek.Pospisil@Sun.COM mutex_exit(&opad->pad_lock); /* current proc will keep cwrd open */
24111861SMarek.Pospisil@Sun.COM
24211861SMarek.Pospisil@Sun.COM /*
24311861SMarek.Pospisil@Sun.COM * If we are in the limited mode, there is nothing to audit and
24411861SMarek.Pospisil@Sun.COM * there could not have been anything to audit, since it is not
24511861SMarek.Pospisil@Sun.COM * possible to switch from the full mode into the limited mode
24611861SMarek.Pospisil@Sun.COM * once the full mode is set.
24711861SMarek.Pospisil@Sun.COM */
24811861SMarek.Pospisil@Sun.COM if (audit_active != C2AUDIT_LOADED)
24911861SMarek.Pospisil@Sun.COM return;
25011861SMarek.Pospisil@Sun.COM
25111861SMarek.Pospisil@Sun.COM /*
25211861SMarek.Pospisil@Sun.COM * finish auditing of parent here so that it will be done
25311861SMarek.Pospisil@Sun.COM * before child has a chance to run. We include the child
25411861SMarek.Pospisil@Sun.COM * pid since the return value in the return token is a dummy
25511861SMarek.Pospisil@Sun.COM * one and contains no useful information (it is included to
25611861SMarek.Pospisil@Sun.COM * make the audit record structure consistant).
25711861SMarek.Pospisil@Sun.COM *
25811861SMarek.Pospisil@Sun.COM * tad_flag is set if auditing is on
25911861SMarek.Pospisil@Sun.COM */
26011861SMarek.Pospisil@Sun.COM if (((t_audit_data_t *)T2A(curthread))->tad_flag)
26111861SMarek.Pospisil@Sun.COM au_uwrite(au_to_arg32(0, "child PID", (uint32_t)cp->p_pid));
26211861SMarek.Pospisil@Sun.COM
26311861SMarek.Pospisil@Sun.COM /*
26411861SMarek.Pospisil@Sun.COM * finish up audit record generation here because child process
26511861SMarek.Pospisil@Sun.COM * is set to run before parent process. We distinguish here
26611861SMarek.Pospisil@Sun.COM * between FORK, FORK1, or VFORK by the saved system call ID.
26711861SMarek.Pospisil@Sun.COM */
26811861SMarek.Pospisil@Sun.COM audit_finish(0, ((t_audit_data_t *)T2A(curthread))->tad_scid, 0, 0);
26911861SMarek.Pospisil@Sun.COM }
27011861SMarek.Pospisil@Sun.COM
27111861SMarek.Pospisil@Sun.COM /*
27211861SMarek.Pospisil@Sun.COM * ROUTINE: AUDIT_PFREE
27311861SMarek.Pospisil@Sun.COM * PURPOSE: deallocate the per-process udit data structure
27411861SMarek.Pospisil@Sun.COM * CALLBY: EXIT
27511861SMarek.Pospisil@Sun.COM * FORK_FAIL
27611861SMarek.Pospisil@Sun.COM * NOTE: all lwp except current one have stopped in SEXITLWPS
27711861SMarek.Pospisil@Sun.COM * why we are single threaded?
27811861SMarek.Pospisil@Sun.COM * . all lwp except current one have stopped in SEXITLWPS.
27911861SMarek.Pospisil@Sun.COM */
28011861SMarek.Pospisil@Sun.COM
28111861SMarek.Pospisil@Sun.COM void
audit_pfree(struct proc * p)28211861SMarek.Pospisil@Sun.COM audit_pfree(struct proc *p) /* proc structure to be freed */
28311861SMarek.Pospisil@Sun.COM
28411861SMarek.Pospisil@Sun.COM { /* AUDIT_PFREE */
28511861SMarek.Pospisil@Sun.COM
28611861SMarek.Pospisil@Sun.COM p_audit_data_t *pad;
28711861SMarek.Pospisil@Sun.COM
28811861SMarek.Pospisil@Sun.COM pad = P2A(p);
28911861SMarek.Pospisil@Sun.COM
29011861SMarek.Pospisil@Sun.COM /* better be a per process audit data structure */
29111861SMarek.Pospisil@Sun.COM ASSERT(pad != (p_audit_data_t *)0);
29211861SMarek.Pospisil@Sun.COM
29311861SMarek.Pospisil@Sun.COM if (pad == pad0) {
29411861SMarek.Pospisil@Sun.COM return;
29511861SMarek.Pospisil@Sun.COM }
29611861SMarek.Pospisil@Sun.COM
29711861SMarek.Pospisil@Sun.COM /* deallocate all auditing resources for this process */
29811861SMarek.Pospisil@Sun.COM au_pathrele(pad->pad_root);
29911861SMarek.Pospisil@Sun.COM au_pathrele(pad->pad_cwd);
30011861SMarek.Pospisil@Sun.COM
30111861SMarek.Pospisil@Sun.COM /*
30211861SMarek.Pospisil@Sun.COM * Since the pad structure is completely overwritten after alloc,
30311861SMarek.Pospisil@Sun.COM * we don't bother to clear it.
30411861SMarek.Pospisil@Sun.COM */
30511861SMarek.Pospisil@Sun.COM
30611861SMarek.Pospisil@Sun.COM kmem_cache_free(au_pad_cache, pad);
30711861SMarek.Pospisil@Sun.COM }
30811861SMarek.Pospisil@Sun.COM
30911861SMarek.Pospisil@Sun.COM /*
31011861SMarek.Pospisil@Sun.COM * ROUTINE: AUDIT_THREAD_CREATE
31111861SMarek.Pospisil@Sun.COM * PURPOSE: allocate per-process thread audit data structure
31211861SMarek.Pospisil@Sun.COM * CALLBY: THREAD_CREATE
31311861SMarek.Pospisil@Sun.COM * NOTE: This is called just after *t was bzero'd.
31411861SMarek.Pospisil@Sun.COM * We are single threaded in this routine.
31511861SMarek.Pospisil@Sun.COM * TODO:
31611861SMarek.Pospisil@Sun.COM * QUESTION:
31711861SMarek.Pospisil@Sun.COM */
31811861SMarek.Pospisil@Sun.COM
31911861SMarek.Pospisil@Sun.COM void
audit_thread_create(kthread_id_t t)32011861SMarek.Pospisil@Sun.COM audit_thread_create(kthread_id_t t)
32111861SMarek.Pospisil@Sun.COM {
32211861SMarek.Pospisil@Sun.COM t_audit_data_t *tad; /* per-thread audit data */
32311861SMarek.Pospisil@Sun.COM
32411861SMarek.Pospisil@Sun.COM tad = kmem_zalloc(sizeof (struct t_audit_data), KM_SLEEP);
32511861SMarek.Pospisil@Sun.COM
32611861SMarek.Pospisil@Sun.COM T2A(t) = tad; /* set up thread audit data ptr */
32711861SMarek.Pospisil@Sun.COM tad->tad_thread = t; /* back ptr to thread: DEBUG */
32811861SMarek.Pospisil@Sun.COM }
32911861SMarek.Pospisil@Sun.COM
33011861SMarek.Pospisil@Sun.COM /*
33111861SMarek.Pospisil@Sun.COM * ROUTINE: AUDIT_THREAD_FREE
33211861SMarek.Pospisil@Sun.COM * PURPOSE: free the per-thread audit data structure
33311861SMarek.Pospisil@Sun.COM * CALLBY: THREAD_FREE
33411861SMarek.Pospisil@Sun.COM * NOTE: most thread data is clear after return
33511861SMarek.Pospisil@Sun.COM */
33611861SMarek.Pospisil@Sun.COM
33711861SMarek.Pospisil@Sun.COM void
audit_thread_free(kthread_t * t)33811861SMarek.Pospisil@Sun.COM audit_thread_free(kthread_t *t)
33911861SMarek.Pospisil@Sun.COM {
34011861SMarek.Pospisil@Sun.COM t_audit_data_t *tad;
34111861SMarek.Pospisil@Sun.COM au_defer_info_t *attr;
34211861SMarek.Pospisil@Sun.COM
34311861SMarek.Pospisil@Sun.COM tad = T2A(t);
34411861SMarek.Pospisil@Sun.COM
34511861SMarek.Pospisil@Sun.COM /* thread audit data must still be set */
34611861SMarek.Pospisil@Sun.COM
34711861SMarek.Pospisil@Sun.COM if (tad == tad0) {
34811861SMarek.Pospisil@Sun.COM return;
34911861SMarek.Pospisil@Sun.COM }
35011861SMarek.Pospisil@Sun.COM
35111861SMarek.Pospisil@Sun.COM if (tad == NULL) {
35211861SMarek.Pospisil@Sun.COM return;
35311861SMarek.Pospisil@Sun.COM }
35411861SMarek.Pospisil@Sun.COM
35511861SMarek.Pospisil@Sun.COM t->t_audit_data = 0;
35611861SMarek.Pospisil@Sun.COM
35711861SMarek.Pospisil@Sun.COM /* must not have any audit record residual */
35811861SMarek.Pospisil@Sun.COM ASSERT(tad->tad_ad == NULL);
35911861SMarek.Pospisil@Sun.COM
36011861SMarek.Pospisil@Sun.COM /* saved path must be empty */
36111861SMarek.Pospisil@Sun.COM ASSERT(tad->tad_aupath == NULL);
36211861SMarek.Pospisil@Sun.COM
36311861SMarek.Pospisil@Sun.COM if (tad->tad_atpath)
36411861SMarek.Pospisil@Sun.COM au_pathrele(tad->tad_atpath);
36511861SMarek.Pospisil@Sun.COM
36611861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_LOADED) {
36711861SMarek.Pospisil@Sun.COM attr = tad->tad_defer_head;
36811861SMarek.Pospisil@Sun.COM while (attr != NULL) {
36911861SMarek.Pospisil@Sun.COM au_defer_info_t *tmp_attr = attr;
37011861SMarek.Pospisil@Sun.COM
37111861SMarek.Pospisil@Sun.COM au_free_rec(attr->audi_ad);
37211861SMarek.Pospisil@Sun.COM
37311861SMarek.Pospisil@Sun.COM attr = attr->audi_next;
37411861SMarek.Pospisil@Sun.COM kmem_free(tmp_attr, sizeof (au_defer_info_t));
37511861SMarek.Pospisil@Sun.COM }
37611861SMarek.Pospisil@Sun.COM }
37711861SMarek.Pospisil@Sun.COM
37811861SMarek.Pospisil@Sun.COM kmem_free(tad, sizeof (*tad));
37911861SMarek.Pospisil@Sun.COM }
38011861SMarek.Pospisil@Sun.COM
38111861SMarek.Pospisil@Sun.COM /*
38211861SMarek.Pospisil@Sun.COM * ROUTINE: AUDIT_FALLOC
38311861SMarek.Pospisil@Sun.COM * PURPOSE: allocating a new file structure
38411861SMarek.Pospisil@Sun.COM * CALLBY: FALLOC
38511861SMarek.Pospisil@Sun.COM * NOTE: file structure already initialized
38611861SMarek.Pospisil@Sun.COM * TODO:
38711861SMarek.Pospisil@Sun.COM * QUESTION:
38811861SMarek.Pospisil@Sun.COM */
38911861SMarek.Pospisil@Sun.COM
39011861SMarek.Pospisil@Sun.COM void
audit_falloc(struct file * fp)39111861SMarek.Pospisil@Sun.COM audit_falloc(struct file *fp)
39211861SMarek.Pospisil@Sun.COM { /* AUDIT_FALLOC */
39311861SMarek.Pospisil@Sun.COM
39411861SMarek.Pospisil@Sun.COM f_audit_data_t *fad;
39511861SMarek.Pospisil@Sun.COM
39611861SMarek.Pospisil@Sun.COM /* allocate per file audit structure if there a'int any */
39711861SMarek.Pospisil@Sun.COM ASSERT(F2A(fp) == NULL);
39811861SMarek.Pospisil@Sun.COM
39911861SMarek.Pospisil@Sun.COM fad = kmem_zalloc(sizeof (struct f_audit_data), KM_SLEEP);
40011861SMarek.Pospisil@Sun.COM
40111861SMarek.Pospisil@Sun.COM F2A(fp) = fad;
40211861SMarek.Pospisil@Sun.COM
40311861SMarek.Pospisil@Sun.COM fad->fad_thread = curthread; /* file audit data back ptr; DEBUG */
40411861SMarek.Pospisil@Sun.COM }
40511861SMarek.Pospisil@Sun.COM
40611861SMarek.Pospisil@Sun.COM /*
40711861SMarek.Pospisil@Sun.COM * ROUTINE: AUDIT_UNFALLOC
40811861SMarek.Pospisil@Sun.COM * PURPOSE: deallocate file audit data structure
40911861SMarek.Pospisil@Sun.COM * CALLBY: CLOSEF
41011861SMarek.Pospisil@Sun.COM * UNFALLOC
41111861SMarek.Pospisil@Sun.COM * NOTE:
41211861SMarek.Pospisil@Sun.COM * TODO:
41311861SMarek.Pospisil@Sun.COM * QUESTION:
41411861SMarek.Pospisil@Sun.COM */
41511861SMarek.Pospisil@Sun.COM
41611861SMarek.Pospisil@Sun.COM void
audit_unfalloc(struct file * fp)41711861SMarek.Pospisil@Sun.COM audit_unfalloc(struct file *fp)
41811861SMarek.Pospisil@Sun.COM {
41911861SMarek.Pospisil@Sun.COM f_audit_data_t *fad;
42011861SMarek.Pospisil@Sun.COM
42111861SMarek.Pospisil@Sun.COM fad = F2A(fp);
42211861SMarek.Pospisil@Sun.COM
42311861SMarek.Pospisil@Sun.COM if (!fad) {
42411861SMarek.Pospisil@Sun.COM return;
42511861SMarek.Pospisil@Sun.COM }
42611861SMarek.Pospisil@Sun.COM if (fad->fad_aupath != NULL) {
42711861SMarek.Pospisil@Sun.COM au_pathrele(fad->fad_aupath);
42811861SMarek.Pospisil@Sun.COM }
42911861SMarek.Pospisil@Sun.COM fp->f_audit_data = 0;
43011861SMarek.Pospisil@Sun.COM kmem_free(fad, sizeof (struct f_audit_data));
43111861SMarek.Pospisil@Sun.COM }
43211861SMarek.Pospisil@Sun.COM
43311861SMarek.Pospisil@Sun.COM uint32_t
audit_getstate()43411861SMarek.Pospisil@Sun.COM audit_getstate()
43511861SMarek.Pospisil@Sun.COM {
43611861SMarek.Pospisil@Sun.COM return (audit_active == C2AUDIT_LOADED &&
43711861SMarek.Pospisil@Sun.COM ((AU_AUDIT_MASK) & U2A(u)->tad_audit));
43811861SMarek.Pospisil@Sun.COM }
439