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