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 /*
27 * Copyright 2026 Oxide Computer Company
28 */
29
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/kmem.h>
33 #include <c2/audit.h>
34 #include <c2/audit_kernel.h>
35
36
37 /* process audit data (pad) cache */
38 kmem_cache_t *au_pad_cache;
39
40 /*
41 * increment audit path reference count
42 */
43 void
au_pathhold(struct audit_path * app)44 au_pathhold(struct audit_path *app)
45 {
46 atomic_inc_32(&app->audp_ref);
47 }
48
49 /*
50 * decrement audit path reference count
51 */
52 void
au_pathrele(struct audit_path * app)53 au_pathrele(struct audit_path *app)
54 {
55 if (atomic_dec_32_nv(&app->audp_ref) > 0)
56 return;
57 kmem_free(app, app->audp_size);
58 }
59
60 /*
61 * allocate a new auditpath
62 * newsect = increment sections count,
63 * charincr = change in strings storage
64 */
65
66 struct audit_path *
au_pathdup(const struct audit_path * oldapp,int newsect,int charincr)67 au_pathdup(const struct audit_path *oldapp, int newsect, int charincr)
68 {
69 struct audit_path *newapp;
70 int i, alloc_size, oldlen;
71 char *oldcp, *newcp;
72
73 newsect = (newsect != 0);
74 oldcp = oldapp->audp_sect[0];
75 oldlen = (oldapp->audp_sect[oldapp->audp_cnt] - oldcp);
76 alloc_size = sizeof (struct audit_path) +
77 (oldapp->audp_cnt + newsect) * sizeof (char *) +
78 oldlen + charincr;
79
80 newapp = kmem_alloc(alloc_size, KM_SLEEP);
81 newapp->audp_ref = 1;
82 newapp->audp_size = alloc_size;
83
84 newapp->audp_cnt = oldapp->audp_cnt + newsect;
85 newcp = (char *)(&newapp->audp_sect[newapp->audp_cnt + 1]);
86 for (i = 0; i <= oldapp->audp_cnt; i++) {
87 newapp->audp_sect[i] = newcp +
88 (oldapp->audp_sect[i] - oldcp);
89 }
90 /*
91 * if this is a new section, set its end
92 * if this is an extended section, reset its end
93 */
94 newapp->audp_sect[newapp->audp_cnt] = newcp + oldlen + charincr;
95 /* copy all of the old strings */
96 bcopy(oldcp, newcp, oldlen);
97
98 return (newapp);
99 }
100
101 /*
102 * allocate an auditpath holding a single path, copied from a NUL-terminated
103 * string. Unlike au_pathdup() this is not anchored by a name lookup, so the
104 * result has just the one section and no attribute paths.
105 */
106 struct audit_path *
au_pathmake(const char * path)107 au_pathmake(const char *path)
108 {
109 struct audit_path *app;
110 int alloc_size, len;
111 char *cp;
112
113 len = strlen(path) + 1;
114 alloc_size = sizeof (struct audit_path) + sizeof (char *) + len;
115
116 app = kmem_alloc(alloc_size, KM_SLEEP);
117 app->audp_ref = 1;
118 app->audp_size = alloc_size;
119 app->audp_cnt = 1;
120
121 cp = (char *)(&app->audp_sect[app->audp_cnt + 1]);
122 app->audp_sect[0] = cp;
123 app->audp_sect[1] = cp + len;
124 bcopy(path, cp, len);
125
126 return (app);
127 }
128
129 /*ARGSUSED1*/
130 static int
au_pad_const(void * vpad,void * priv,int flags)131 au_pad_const(void *vpad, void *priv, int flags)
132 {
133 p_audit_data_t *pad = vpad;
134
135 mutex_init(&pad->pad_lock, NULL, MUTEX_DEFAULT, NULL);
136
137 return (0);
138 }
139
140 /*ARGSUSED1*/
141 static void
au_pad_destr(void * vpad,void * priv)142 au_pad_destr(void *vpad, void *priv)
143 {
144 p_audit_data_t *pad = vpad;
145
146 mutex_destroy(&pad->pad_lock);
147 }
148
149 void
au_pad_init()150 au_pad_init()
151 {
152 au_pad_cache = kmem_cache_create("audit_proc",
153 sizeof (p_audit_data_t), 0, au_pad_const, au_pad_destr,
154 NULL, NULL, NULL, 0);
155 }
156