xref: /onnv-gate/usr/src/uts/common/os/audit_zone.c (revision 11861:a63258283f8f)
1*11861SMarek.Pospisil@Sun.COM /*
2*11861SMarek.Pospisil@Sun.COM  * CDDL HEADER START
3*11861SMarek.Pospisil@Sun.COM  *
4*11861SMarek.Pospisil@Sun.COM  * The contents of this file are subject to the terms of the
5*11861SMarek.Pospisil@Sun.COM  * Common Development and Distribution License (the "License").
6*11861SMarek.Pospisil@Sun.COM  * You may not use this file except in compliance with the License.
7*11861SMarek.Pospisil@Sun.COM  *
8*11861SMarek.Pospisil@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*11861SMarek.Pospisil@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*11861SMarek.Pospisil@Sun.COM  * See the License for the specific language governing permissions
11*11861SMarek.Pospisil@Sun.COM  * and limitations under the License.
12*11861SMarek.Pospisil@Sun.COM  *
13*11861SMarek.Pospisil@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*11861SMarek.Pospisil@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*11861SMarek.Pospisil@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*11861SMarek.Pospisil@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*11861SMarek.Pospisil@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*11861SMarek.Pospisil@Sun.COM  *
19*11861SMarek.Pospisil@Sun.COM  * CDDL HEADER END
20*11861SMarek.Pospisil@Sun.COM  */
21*11861SMarek.Pospisil@Sun.COM /*
22*11861SMarek.Pospisil@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23*11861SMarek.Pospisil@Sun.COM  * Use is subject to license terms.
24*11861SMarek.Pospisil@Sun.COM  */
25*11861SMarek.Pospisil@Sun.COM 
26*11861SMarek.Pospisil@Sun.COM 
27*11861SMarek.Pospisil@Sun.COM #include <c2/audit.h>
28*11861SMarek.Pospisil@Sun.COM #include <c2/audit_kernel.h>
29*11861SMarek.Pospisil@Sun.COM #include <c2/audit_record.h>
30*11861SMarek.Pospisil@Sun.COM #include <sys/kmem.h>
31*11861SMarek.Pospisil@Sun.COM #include <sys/param.h>
32*11861SMarek.Pospisil@Sun.COM #include <sys/systm.h>
33*11861SMarek.Pospisil@Sun.COM #include <sys/taskq.h>
34*11861SMarek.Pospisil@Sun.COM #include <sys/t_lock.h>
35*11861SMarek.Pospisil@Sun.COM #include <sys/thread.h>
36*11861SMarek.Pospisil@Sun.COM #include <sys/types.h>
37*11861SMarek.Pospisil@Sun.COM #include <sys/zone.h>
38*11861SMarek.Pospisil@Sun.COM 
39*11861SMarek.Pospisil@Sun.COM zone_key_t au_zone_key;
40*11861SMarek.Pospisil@Sun.COM 
41*11861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
42*11861SMarek.Pospisil@Sun.COM static void *
43*11861SMarek.Pospisil@Sun.COM au_zone_init(zoneid_t zone)
44*11861SMarek.Pospisil@Sun.COM {
45*11861SMarek.Pospisil@Sun.COM 	au_kcontext_t	*kctx = kmem_zalloc(sizeof (au_kcontext_t), KM_SLEEP);
46*11861SMarek.Pospisil@Sun.COM 	static au_kcontext_t	*global_kctx = NULL;
47*11861SMarek.Pospisil@Sun.COM 
48*11861SMarek.Pospisil@Sun.COM 	/*
49*11861SMarek.Pospisil@Sun.COM 	 * INGLOBALZONE(curproc) is invalid at this point, so check for
50*11861SMarek.Pospisil@Sun.COM 	 * zone 0
51*11861SMarek.Pospisil@Sun.COM 	 */
52*11861SMarek.Pospisil@Sun.COM 
53*11861SMarek.Pospisil@Sun.COM 	if (zone == 0) {
54*11861SMarek.Pospisil@Sun.COM 		global_kctx = kctx;
55*11861SMarek.Pospisil@Sun.COM 		global_zone->zone_audit_kctxt = kctx;
56*11861SMarek.Pospisil@Sun.COM 	} else {
57*11861SMarek.Pospisil@Sun.COM 		kctx->auk_policy = global_kctx->auk_policy;
58*11861SMarek.Pospisil@Sun.COM 		curproc->p_zone->zone_audit_kctxt = kctx;
59*11861SMarek.Pospisil@Sun.COM 	}
60*11861SMarek.Pospisil@Sun.COM 	kctx->auk_valid = AUK_VALID;
61*11861SMarek.Pospisil@Sun.COM 	kctx->auk_zid = zone;
62*11861SMarek.Pospisil@Sun.COM 
63*11861SMarek.Pospisil@Sun.COM 	kctx->auk_info.ai_termid.at_type = AU_IPv4;
64*11861SMarek.Pospisil@Sun.COM 	kctx->auk_info.ai_auid = AU_NOAUDITID;
65*11861SMarek.Pospisil@Sun.COM 	kctx->auk_auditstate = AUC_INIT_AUDIT;
66*11861SMarek.Pospisil@Sun.COM 
67*11861SMarek.Pospisil@Sun.COM 	/* setup defaults for audit queue flow control */
68*11861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.hiwater = AQ_HIWATER;
69*11861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.lowater = AQ_LOWATER;
70*11861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.bufsz   = AQ_BUFSZ;
71*11861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.buflen  = AQ_BUFSZ;
72*11861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.delay   = AQ_DELAY;
73*11861SMarek.Pospisil@Sun.COM 
74*11861SMarek.Pospisil@Sun.COM 	/* statistics per zone */
75*11861SMarek.Pospisil@Sun.COM 	kctx->auk_statistics.as_version  = TOKEN_VERSION;
76*11861SMarek.Pospisil@Sun.COM 	kctx->auk_statistics.as_numevent = MAX_KEVENTS;
77*11861SMarek.Pospisil@Sun.COM 
78*11861SMarek.Pospisil@Sun.COM 	/* door IO buffer: */
79*11861SMarek.Pospisil@Sun.COM 	kctx->auk_dbuffer =
80*11861SMarek.Pospisil@Sun.COM 	    kmem_alloc(AU_DBUF_HEADER + kctx->auk_queue.bufsz, KM_SLEEP);
81*11861SMarek.Pospisil@Sun.COM 
82*11861SMarek.Pospisil@Sun.COM 	/* locks and cv's */
83*11861SMarek.Pospisil@Sun.COM 
84*11861SMarek.Pospisil@Sun.COM 	mutex_init(&(kctx->auk_eagain_mutex), NULL, MUTEX_DEFAULT, NULL);
85*11861SMarek.Pospisil@Sun.COM 	cv_init(&(kctx->auk_eagain_cv), NULL, CV_DRIVER, NULL);
86*11861SMarek.Pospisil@Sun.COM 
87*11861SMarek.Pospisil@Sun.COM 	mutex_init(&(kctx->auk_svc_lock), NULL, MUTEX_DEFAULT, NULL);
88*11861SMarek.Pospisil@Sun.COM 
89*11861SMarek.Pospisil@Sun.COM 	mutex_init(&(kctx->auk_queue.lock), NULL, MUTEX_DEFAULT, NULL);
90*11861SMarek.Pospisil@Sun.COM 	cv_init(&(kctx->auk_queue.write_cv), NULL, CV_DRIVER, NULL);
91*11861SMarek.Pospisil@Sun.COM 	cv_init(&(kctx->auk_queue.read_cv), NULL, CV_DRIVER, NULL);
92*11861SMarek.Pospisil@Sun.COM 
93*11861SMarek.Pospisil@Sun.COM 	return (kctx);
94*11861SMarek.Pospisil@Sun.COM }
95*11861SMarek.Pospisil@Sun.COM 
96*11861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
97*11861SMarek.Pospisil@Sun.COM static void
98*11861SMarek.Pospisil@Sun.COM au_zone_shutdown(zoneid_t zone, void *arg)
99*11861SMarek.Pospisil@Sun.COM {
100*11861SMarek.Pospisil@Sun.COM 	au_kcontext_t	*kctx = arg;
101*11861SMarek.Pospisil@Sun.COM 
102*11861SMarek.Pospisil@Sun.COM 	if (audit_active == C2AUDIT_LOADED && (kctx->auk_zid == GLOBAL_ZONEID ||
103*11861SMarek.Pospisil@Sun.COM 	    (audit_policy | AUDIT_PERZONE)) && (kctx->auk_current_vp != NULL))
104*11861SMarek.Pospisil@Sun.COM 		(void) au_doormsg(kctx, AU_DBUF_SHUTDOWN, NULL);
105*11861SMarek.Pospisil@Sun.COM 
106*11861SMarek.Pospisil@Sun.COM 	kctx->auk_valid = AUK_INVALID;
107*11861SMarek.Pospisil@Sun.COM 
108*11861SMarek.Pospisil@Sun.COM 	/* shutdown the output thread if it is still running */
109*11861SMarek.Pospisil@Sun.COM 	kctx->auk_auditstate = AUC_NOAUDIT;
110*11861SMarek.Pospisil@Sun.COM 
111*11861SMarek.Pospisil@Sun.COM 	if (kctx->auk_output_active) {
112*11861SMarek.Pospisil@Sun.COM 		mutex_enter(&(kctx->auk_queue.lock));
113*11861SMarek.Pospisil@Sun.COM 		cv_broadcast(&(kctx->auk_queue.read_cv));
114*11861SMarek.Pospisil@Sun.COM 		mutex_exit(&(kctx->auk_queue.lock));
115*11861SMarek.Pospisil@Sun.COM 
116*11861SMarek.Pospisil@Sun.COM 		taskq_destroy(kctx->auk_taskq);
117*11861SMarek.Pospisil@Sun.COM 	}
118*11861SMarek.Pospisil@Sun.COM }
119*11861SMarek.Pospisil@Sun.COM 
120*11861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
121*11861SMarek.Pospisil@Sun.COM static void
122*11861SMarek.Pospisil@Sun.COM au_zone_destroy(zoneid_t zone, void *arg)
123*11861SMarek.Pospisil@Sun.COM {
124*11861SMarek.Pospisil@Sun.COM 	au_kcontext_t	*kctx = arg;
125*11861SMarek.Pospisil@Sun.COM 
126*11861SMarek.Pospisil@Sun.COM 	ASSERT(kctx->auk_auditstate == AUC_NOAUDIT);
127*11861SMarek.Pospisil@Sun.COM 
128*11861SMarek.Pospisil@Sun.COM 	mutex_destroy(&(kctx->auk_eagain_mutex));
129*11861SMarek.Pospisil@Sun.COM 	cv_destroy(&(kctx->auk_eagain_cv));
130*11861SMarek.Pospisil@Sun.COM 
131*11861SMarek.Pospisil@Sun.COM 	mutex_destroy(&(kctx->auk_svc_lock));
132*11861SMarek.Pospisil@Sun.COM 
133*11861SMarek.Pospisil@Sun.COM 	mutex_enter(&(kctx->auk_queue.lock));
134*11861SMarek.Pospisil@Sun.COM 	if (kctx->auk_queue.head != NULL) {
135*11861SMarek.Pospisil@Sun.COM 		au_free_rec(kctx->auk_queue.head);
136*11861SMarek.Pospisil@Sun.COM 	}
137*11861SMarek.Pospisil@Sun.COM 	mutex_exit(&(kctx->auk_queue.lock));
138*11861SMarek.Pospisil@Sun.COM 
139*11861SMarek.Pospisil@Sun.COM 	mutex_destroy(&(kctx->auk_queue.lock));
140*11861SMarek.Pospisil@Sun.COM 
141*11861SMarek.Pospisil@Sun.COM 	cv_destroy(&(kctx->auk_queue.write_cv));
142*11861SMarek.Pospisil@Sun.COM 	cv_destroy(&(kctx->auk_queue.read_cv));
143*11861SMarek.Pospisil@Sun.COM 
144*11861SMarek.Pospisil@Sun.COM 	kmem_free(kctx->auk_dbuffer, AU_DBUF_HEADER + kctx->auk_queue.bufsz);
145*11861SMarek.Pospisil@Sun.COM 
146*11861SMarek.Pospisil@Sun.COM 	kmem_free(kctx, sizeof (au_kcontext_t));
147*11861SMarek.Pospisil@Sun.COM }
148*11861SMarek.Pospisil@Sun.COM 
149*11861SMarek.Pospisil@Sun.COM void
150*11861SMarek.Pospisil@Sun.COM au_zone_setup()
151*11861SMarek.Pospisil@Sun.COM {
152*11861SMarek.Pospisil@Sun.COM 	zone_key_create(&au_zone_key, au_zone_init, au_zone_shutdown,
153*11861SMarek.Pospisil@Sun.COM 	    au_zone_destroy);
154*11861SMarek.Pospisil@Sun.COM 
155*11861SMarek.Pospisil@Sun.COM }
156*11861SMarek.Pospisil@Sun.COM 
157*11861SMarek.Pospisil@Sun.COM int
158*11861SMarek.Pospisil@Sun.COM au_zone_getstate(const au_kcontext_t *context)
159*11861SMarek.Pospisil@Sun.COM {
160*11861SMarek.Pospisil@Sun.COM 	au_kcontext_t *tcontext;
161*11861SMarek.Pospisil@Sun.COM 
162*11861SMarek.Pospisil@Sun.COM 	if (context != NULL)
163*11861SMarek.Pospisil@Sun.COM 		return (context->auk_auditstate);
164*11861SMarek.Pospisil@Sun.COM 	tcontext = GET_KCTX_PZ;
165*11861SMarek.Pospisil@Sun.COM 	return (tcontext->auk_auditstate);
166*11861SMarek.Pospisil@Sun.COM }
167