xref: /onnv-gate/usr/src/uts/common/os/audit_zone.c (revision 11965:a7d9676a9f85)
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 /*
2211861SMarek.Pospisil@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
2311861SMarek.Pospisil@Sun.COM  * Use is subject to license terms.
2411861SMarek.Pospisil@Sun.COM  */
2511861SMarek.Pospisil@Sun.COM 
2611861SMarek.Pospisil@Sun.COM 
2711861SMarek.Pospisil@Sun.COM #include <c2/audit.h>
2811861SMarek.Pospisil@Sun.COM #include <c2/audit_kernel.h>
2911861SMarek.Pospisil@Sun.COM #include <c2/audit_record.h>
3011861SMarek.Pospisil@Sun.COM #include <sys/kmem.h>
3111861SMarek.Pospisil@Sun.COM #include <sys/param.h>
3211861SMarek.Pospisil@Sun.COM #include <sys/systm.h>
3311861SMarek.Pospisil@Sun.COM #include <sys/taskq.h>
3411861SMarek.Pospisil@Sun.COM #include <sys/t_lock.h>
3511861SMarek.Pospisil@Sun.COM #include <sys/thread.h>
3611861SMarek.Pospisil@Sun.COM #include <sys/types.h>
3711861SMarek.Pospisil@Sun.COM #include <sys/zone.h>
3811861SMarek.Pospisil@Sun.COM 
3911861SMarek.Pospisil@Sun.COM zone_key_t au_zone_key;
4011861SMarek.Pospisil@Sun.COM 
4111861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
4211861SMarek.Pospisil@Sun.COM static void *
au_zone_init(zoneid_t zone)4311861SMarek.Pospisil@Sun.COM au_zone_init(zoneid_t zone)
4411861SMarek.Pospisil@Sun.COM {
4511861SMarek.Pospisil@Sun.COM 	au_kcontext_t	*kctx = kmem_zalloc(sizeof (au_kcontext_t), KM_SLEEP);
4611861SMarek.Pospisil@Sun.COM 	static au_kcontext_t	*global_kctx = NULL;
4711861SMarek.Pospisil@Sun.COM 
4811861SMarek.Pospisil@Sun.COM 	/*
4911861SMarek.Pospisil@Sun.COM 	 * INGLOBALZONE(curproc) is invalid at this point, so check for
5011861SMarek.Pospisil@Sun.COM 	 * zone 0
5111861SMarek.Pospisil@Sun.COM 	 */
5211861SMarek.Pospisil@Sun.COM 
5311861SMarek.Pospisil@Sun.COM 	if (zone == 0) {
5411861SMarek.Pospisil@Sun.COM 		global_kctx = kctx;
5511861SMarek.Pospisil@Sun.COM 		global_zone->zone_audit_kctxt = kctx;
5611861SMarek.Pospisil@Sun.COM 	} else {
5711861SMarek.Pospisil@Sun.COM 		kctx->auk_policy = global_kctx->auk_policy;
5811861SMarek.Pospisil@Sun.COM 		curproc->p_zone->zone_audit_kctxt = kctx;
5911861SMarek.Pospisil@Sun.COM 	}
6011861SMarek.Pospisil@Sun.COM 	kctx->auk_valid = AUK_VALID;
6111861SMarek.Pospisil@Sun.COM 	kctx->auk_zid = zone;
6211861SMarek.Pospisil@Sun.COM 
6311861SMarek.Pospisil@Sun.COM 	kctx->auk_info.ai_termid.at_type = AU_IPv4;
6411861SMarek.Pospisil@Sun.COM 	kctx->auk_info.ai_auid = AU_NOAUDITID;
6511861SMarek.Pospisil@Sun.COM 	kctx->auk_auditstate = AUC_INIT_AUDIT;
6611861SMarek.Pospisil@Sun.COM 
6711861SMarek.Pospisil@Sun.COM 	/* setup defaults for audit queue flow control */
6811861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.hiwater = AQ_HIWATER;
6911861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.lowater = AQ_LOWATER;
7011861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.bufsz   = AQ_BUFSZ;
7111861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.buflen  = AQ_BUFSZ;
7211861SMarek.Pospisil@Sun.COM 	kctx->auk_queue.delay   = AQ_DELAY;
7311861SMarek.Pospisil@Sun.COM 
7411861SMarek.Pospisil@Sun.COM 	/* statistics per zone */
7511861SMarek.Pospisil@Sun.COM 	kctx->auk_statistics.as_version  = TOKEN_VERSION;
7611861SMarek.Pospisil@Sun.COM 	kctx->auk_statistics.as_numevent = MAX_KEVENTS;
7711861SMarek.Pospisil@Sun.COM 
7811861SMarek.Pospisil@Sun.COM 	/* door IO buffer: */
7911861SMarek.Pospisil@Sun.COM 	kctx->auk_dbuffer =
8011861SMarek.Pospisil@Sun.COM 	    kmem_alloc(AU_DBUF_HEADER + kctx->auk_queue.bufsz, KM_SLEEP);
8111861SMarek.Pospisil@Sun.COM 
8211861SMarek.Pospisil@Sun.COM 	/* locks and cv's */
8311861SMarek.Pospisil@Sun.COM 
8411861SMarek.Pospisil@Sun.COM 	mutex_init(&(kctx->auk_eagain_mutex), NULL, MUTEX_DEFAULT, NULL);
8511861SMarek.Pospisil@Sun.COM 	cv_init(&(kctx->auk_eagain_cv), NULL, CV_DRIVER, NULL);
8611861SMarek.Pospisil@Sun.COM 
8711861SMarek.Pospisil@Sun.COM 	mutex_init(&(kctx->auk_svc_lock), NULL, MUTEX_DEFAULT, NULL);
8811861SMarek.Pospisil@Sun.COM 
8911861SMarek.Pospisil@Sun.COM 	mutex_init(&(kctx->auk_queue.lock), NULL, MUTEX_DEFAULT, NULL);
9011861SMarek.Pospisil@Sun.COM 	cv_init(&(kctx->auk_queue.write_cv), NULL, CV_DRIVER, NULL);
9111861SMarek.Pospisil@Sun.COM 	cv_init(&(kctx->auk_queue.read_cv), NULL, CV_DRIVER, NULL);
9211861SMarek.Pospisil@Sun.COM 
9311861SMarek.Pospisil@Sun.COM 	return (kctx);
9411861SMarek.Pospisil@Sun.COM }
9511861SMarek.Pospisil@Sun.COM 
9611861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
9711861SMarek.Pospisil@Sun.COM static void
au_zone_shutdown(zoneid_t zone,void * arg)9811861SMarek.Pospisil@Sun.COM au_zone_shutdown(zoneid_t zone, void *arg)
9911861SMarek.Pospisil@Sun.COM {
10011861SMarek.Pospisil@Sun.COM 	au_kcontext_t	*kctx = arg;
10111861SMarek.Pospisil@Sun.COM 
10211861SMarek.Pospisil@Sun.COM 	if (audit_active == C2AUDIT_LOADED && (kctx->auk_zid == GLOBAL_ZONEID ||
10311861SMarek.Pospisil@Sun.COM 	    (audit_policy | AUDIT_PERZONE)) && (kctx->auk_current_vp != NULL))
10411861SMarek.Pospisil@Sun.COM 		(void) au_doormsg(kctx, AU_DBUF_SHUTDOWN, NULL);
10511861SMarek.Pospisil@Sun.COM 
10611861SMarek.Pospisil@Sun.COM 	kctx->auk_valid = AUK_INVALID;
10711861SMarek.Pospisil@Sun.COM 
10811861SMarek.Pospisil@Sun.COM 	/* shutdown the output thread if it is still running */
10911861SMarek.Pospisil@Sun.COM 	kctx->auk_auditstate = AUC_NOAUDIT;
11011861SMarek.Pospisil@Sun.COM 
11111861SMarek.Pospisil@Sun.COM 	if (kctx->auk_output_active) {
11211861SMarek.Pospisil@Sun.COM 		mutex_enter(&(kctx->auk_queue.lock));
11311861SMarek.Pospisil@Sun.COM 		cv_broadcast(&(kctx->auk_queue.read_cv));
11411861SMarek.Pospisil@Sun.COM 		mutex_exit(&(kctx->auk_queue.lock));
11511861SMarek.Pospisil@Sun.COM 
11611861SMarek.Pospisil@Sun.COM 		taskq_destroy(kctx->auk_taskq);
11711861SMarek.Pospisil@Sun.COM 	}
11811861SMarek.Pospisil@Sun.COM }
11911861SMarek.Pospisil@Sun.COM 
12011861SMarek.Pospisil@Sun.COM /*ARGSUSED*/
12111861SMarek.Pospisil@Sun.COM static void
au_zone_destroy(zoneid_t zone,void * arg)12211861SMarek.Pospisil@Sun.COM au_zone_destroy(zoneid_t zone, void *arg)
12311861SMarek.Pospisil@Sun.COM {
12411861SMarek.Pospisil@Sun.COM 	au_kcontext_t	*kctx = arg;
12511861SMarek.Pospisil@Sun.COM 
12611861SMarek.Pospisil@Sun.COM 	ASSERT(kctx->auk_auditstate == AUC_NOAUDIT);
12711861SMarek.Pospisil@Sun.COM 
12811861SMarek.Pospisil@Sun.COM 	mutex_destroy(&(kctx->auk_eagain_mutex));
12911861SMarek.Pospisil@Sun.COM 	cv_destroy(&(kctx->auk_eagain_cv));
13011861SMarek.Pospisil@Sun.COM 
13111861SMarek.Pospisil@Sun.COM 	mutex_destroy(&(kctx->auk_svc_lock));
13211861SMarek.Pospisil@Sun.COM 
13311861SMarek.Pospisil@Sun.COM 	mutex_enter(&(kctx->auk_queue.lock));
13411861SMarek.Pospisil@Sun.COM 	if (kctx->auk_queue.head != NULL) {
13511861SMarek.Pospisil@Sun.COM 		au_free_rec(kctx->auk_queue.head);
13611861SMarek.Pospisil@Sun.COM 	}
13711861SMarek.Pospisil@Sun.COM 	mutex_exit(&(kctx->auk_queue.lock));
13811861SMarek.Pospisil@Sun.COM 
13911861SMarek.Pospisil@Sun.COM 	mutex_destroy(&(kctx->auk_queue.lock));
14011861SMarek.Pospisil@Sun.COM 
14111861SMarek.Pospisil@Sun.COM 	cv_destroy(&(kctx->auk_queue.write_cv));
14211861SMarek.Pospisil@Sun.COM 	cv_destroy(&(kctx->auk_queue.read_cv));
14311861SMarek.Pospisil@Sun.COM 
144*11965SMarek.Pospisil@Sun.COM 	kmem_free(kctx->auk_dbuffer, AU_DBUF_HEADER + kctx->auk_queue.buflen);
14511861SMarek.Pospisil@Sun.COM 
14611861SMarek.Pospisil@Sun.COM 	kmem_free(kctx, sizeof (au_kcontext_t));
14711861SMarek.Pospisil@Sun.COM }
14811861SMarek.Pospisil@Sun.COM 
14911861SMarek.Pospisil@Sun.COM void
au_zone_setup()15011861SMarek.Pospisil@Sun.COM au_zone_setup()
15111861SMarek.Pospisil@Sun.COM {
15211861SMarek.Pospisil@Sun.COM 	zone_key_create(&au_zone_key, au_zone_init, au_zone_shutdown,
15311861SMarek.Pospisil@Sun.COM 	    au_zone_destroy);
15411861SMarek.Pospisil@Sun.COM 
15511861SMarek.Pospisil@Sun.COM }
15611861SMarek.Pospisil@Sun.COM 
15711861SMarek.Pospisil@Sun.COM int
au_zone_getstate(const au_kcontext_t * context)15811861SMarek.Pospisil@Sun.COM au_zone_getstate(const au_kcontext_t *context)
15911861SMarek.Pospisil@Sun.COM {
16011861SMarek.Pospisil@Sun.COM 	au_kcontext_t *tcontext;
16111861SMarek.Pospisil@Sun.COM 
16211861SMarek.Pospisil@Sun.COM 	if (context != NULL)
16311861SMarek.Pospisil@Sun.COM 		return (context->auk_auditstate);
16411861SMarek.Pospisil@Sun.COM 	tcontext = GET_KCTX_PZ;
16511861SMarek.Pospisil@Sun.COM 	return (tcontext->auk_auditstate);
16611861SMarek.Pospisil@Sun.COM }
167