1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/param.h>
27 #include <sys/types.h>
28 #include <sys/kmem.h>
29 #include <c2/audit.h>
30 #include <c2/audit_kernel.h>
31 
32 
33 /* process audit data (pad) cache */
34 kmem_cache_t *au_pad_cache;
35 
36 /*
37  * increment audit path reference count
38  */
39 void
au_pathhold(struct audit_path * app)40 au_pathhold(struct audit_path *app)
41 {
42 	atomic_inc_32(&app->audp_ref);
43 }
44 
45 /*
46  * decrement audit path reference count
47  */
48 void
au_pathrele(struct audit_path * app)49 au_pathrele(struct audit_path *app)
50 {
51 	if (atomic_dec_32_nv(&app->audp_ref) > 0)
52 		return;
53 	kmem_free(app, app->audp_size);
54 }
55 
56 /*
57  * allocate a new auditpath
58  *	newsect = increment sections count,
59  *	charincr = change in strings storage
60  */
61 
62 struct audit_path *
au_pathdup(const struct audit_path * oldapp,int newsect,int charincr)63 au_pathdup(const struct audit_path *oldapp, int newsect, int charincr)
64 {
65 	struct audit_path	*newapp;
66 	int	i, alloc_size, oldlen;
67 	char	*oldcp, *newcp;
68 
69 	newsect = (newsect != 0);
70 	oldcp = oldapp->audp_sect[0];
71 	oldlen = (oldapp->audp_sect[oldapp->audp_cnt] - oldcp);
72 	alloc_size = sizeof (struct audit_path) +
73 	    (oldapp->audp_cnt + newsect) * sizeof (char *) +
74 	    oldlen + charincr;
75 
76 	newapp = kmem_alloc(alloc_size, KM_SLEEP);
77 	newapp->audp_ref = 1;
78 	newapp->audp_size = alloc_size;
79 
80 	newapp->audp_cnt = oldapp->audp_cnt + newsect;
81 	newcp = (char *)(&newapp->audp_sect[newapp->audp_cnt + 1]);
82 	for (i = 0; i <= oldapp->audp_cnt; i++) {
83 		newapp->audp_sect[i] = newcp +
84 		    (oldapp->audp_sect[i] - oldcp);
85 	}
86 	/*
87 	 * if this is a new section, set its end
88 	 * if this is an extended section, reset its end
89 	 */
90 	newapp->audp_sect[newapp->audp_cnt] = newcp + oldlen + charincr;
91 	/* copy all of the old strings */
92 	bcopy(oldcp, newcp, oldlen);
93 
94 	return (newapp);
95 }
96 
97 /*ARGSUSED1*/
98 static int
au_pad_const(void * vpad,void * priv,int flags)99 au_pad_const(void *vpad, void *priv, int flags)
100 {
101 	p_audit_data_t *pad = vpad;
102 
103 	mutex_init(&pad->pad_lock, NULL, MUTEX_DEFAULT, NULL);
104 
105 	return (0);
106 }
107 
108 /*ARGSUSED1*/
109 static void
au_pad_destr(void * vpad,void * priv)110 au_pad_destr(void *vpad, void *priv)
111 {
112 	p_audit_data_t *pad = vpad;
113 
114 	mutex_destroy(&pad->pad_lock);
115 }
116 
117 void
au_pad_init()118 au_pad_init()
119 {
120 	au_pad_cache = kmem_cache_create("audit_proc",
121 	    sizeof (p_audit_data_t), 0, au_pad_const, au_pad_destr,
122 	    NULL, NULL, NULL, 0);
123 }
124