Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/os/sid.c
+++ new/usr/src/uts/common/os/sid.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Sid manipulation (stubs).
29 29 */
30 30
31 31 #include <sys/atomic.h>
32 32 #include <sys/avl.h>
33 33 #include <sys/cmn_err.h>
34 34 #include <sys/kmem.h>
35 35 #include <sys/mutex.h>
36 36 #include <sys/sid.h>
37 37 #include <sys/sysmacros.h>
38 38 #include <sys/systm.h>
39 39 #include <sys/kidmap.h>
40 40 #include <sys/idmap.h>
41 41
42 42 static kmutex_t sid_lock;
43 43 static avl_tree_t sid_tree;
44 44 static boolean_t sid_inited = B_FALSE;
45 45
46 46 static ksiddomain_t
47 47 *ksid_enterdomain(const char *dom)
48 48 {
49 49 size_t len = strlen(dom) + 1;
50 50 ksiddomain_t *res;
51 51
52 52 ASSERT(MUTEX_HELD(&sid_lock));
53 53 res = kmem_alloc(sizeof (ksiddomain_t), KM_SLEEP);
54 54 res->kd_len = (uint_t)len;
55 55 res->kd_name = kmem_alloc(len, KM_SLEEP);
56 56 bcopy(dom, res->kd_name, len);
57 57
58 58 res->kd_ref = 1;
59 59
60 60 avl_add(&sid_tree, res);
61 61
62 62 return (res);
63 63 }
64 64
65 65 void
66 66 ksid_hold(ksid_t *ks)
67 67 {
68 68 if (ks->ks_domain != NULL)
69 69 ksiddomain_hold(ks->ks_domain);
70 70 }
71 71
↓ open down ↓ |
71 lines elided |
↑ open up ↑ |
72 72 void
73 73 ksid_rele(ksid_t *ks)
74 74 {
75 75 if (ks->ks_domain != NULL)
76 76 ksiddomain_rele(ks->ks_domain);
77 77 }
78 78
79 79 void
80 80 ksiddomain_hold(ksiddomain_t *kd)
81 81 {
82 - atomic_add_32(&kd->kd_ref, 1);
82 + atomic_inc_32(&kd->kd_ref);
83 83 }
84 84
85 85 void
86 86 ksiddomain_rele(ksiddomain_t *kd)
87 87 {
88 - if (atomic_add_32_nv(&kd->kd_ref, -1) == 0) {
88 + if (atomic_dec_32_nv(&kd->kd_ref) == 0) {
89 89 /*
90 90 * The kd reference can only be incremented from 0 when
91 91 * the sid_lock is held; so we lock and then check need to
92 92 * check for 0 again.
93 93 */
94 94 mutex_enter(&sid_lock);
95 95 if (kd->kd_ref == 0) {
96 96 avl_remove(&sid_tree, kd);
97 97 kmem_free(kd->kd_name, kd->kd_len);
98 98 kmem_free(kd, sizeof (*kd));
99 99 }
100 100 mutex_exit(&sid_lock);
101 101 }
102 102 }
103 103
104 104 void
105 105 ksidlist_hold(ksidlist_t *ksl)
106 106 {
107 - atomic_add_32(&ksl->ksl_ref, 1);
107 + atomic_inc_32(&ksl->ksl_ref);
108 108 }
109 109
110 110 void
111 111 ksidlist_rele(ksidlist_t *ksl)
112 112 {
113 - if (atomic_add_32_nv(&ksl->ksl_ref, -1) == 0) {
113 + if (atomic_dec_32_nv(&ksl->ksl_ref) == 0) {
114 114 int i;
115 115
116 116 for (i = 0; i < ksl->ksl_nsid; i++)
117 117 ksid_rele(&ksl->ksl_sids[i]);
118 118
119 119 kmem_free(ksl, KSIDLIST_MEM(ksl->ksl_nsid));
120 120 }
121 121 }
122 122
123 123 static int
124 124 ksid_cmp(const void *a, const void *b)
125 125 {
126 126 const ksiddomain_t *ap = a;
127 127 const ksiddomain_t *bp = b;
128 128 int res;
129 129
130 130 res = strcmp(ap->kd_name, bp->kd_name);
131 131 if (res > 0)
132 132 return (1);
133 133 if (res != 0)
134 134 return (-1);
135 135 return (0);
136 136 }
137 137
138 138 /*
139 139 * Lookup the named domain in the AVL tree.
140 140 * If no entry is found, add the domain to the AVL tree.
141 141 * The domain is returned held and needs to be released
142 142 * when done.
143 143 */
144 144 ksiddomain_t
145 145 *ksid_lookupdomain(const char *dom)
146 146 {
147 147 ksiddomain_t *res;
148 148 ksiddomain_t tmpl;
149 149
150 150 mutex_enter(&sid_lock);
151 151
152 152 if (!sid_inited) {
153 153 avl_create(&sid_tree, ksid_cmp, sizeof (ksiddomain_t),
154 154 offsetof(ksiddomain_t, kd_link));
155 155
156 156 res = ksid_enterdomain(dom);
157 157 sid_inited = B_TRUE;
158 158 mutex_exit(&sid_lock);
159 159 return (res);
160 160 }
161 161
162 162 tmpl.kd_name = (char *)dom;
163 163
164 164 res = avl_find(&sid_tree, &tmpl, NULL);
165 165 if (res == NULL) {
166 166 res = ksid_enterdomain(dom);
167 167 } else {
168 168 ksiddomain_hold(res);
169 169 }
170 170
171 171 mutex_exit(&sid_lock);
172 172 return (res);
173 173 }
174 174
175 175 const char *
176 176 ksid_getdomain(ksid_t *ks)
177 177 {
178 178 return (ks->ks_domain->kd_name);
179 179 }
180 180
181 181 uint_t
182 182 ksid_getrid(ksid_t *ks)
183 183 {
184 184 return (ks->ks_rid);
185 185 }
186 186
187 187 uid_t
188 188 ksid_getid(ksid_t *ks)
189 189 {
190 190 return (ks->ks_id);
191 191 }
192 192
193 193 int
194 194 ksid_lookupbyuid(zone_t *zone, uid_t id, ksid_t *res)
195 195 {
196 196 const char *sid_prefix;
197 197
198 198 if (kidmap_getsidbyuid(zone, id, &sid_prefix, &res->ks_rid)
199 199 != IDMAP_SUCCESS)
200 200 return (-1);
201 201
202 202 res->ks_domain = ksid_lookupdomain(sid_prefix);
203 203
204 204 res->ks_id = id;
205 205
206 206 return (0);
207 207 }
208 208
209 209 int
210 210 ksid_lookupbygid(zone_t *zone, gid_t id, ksid_t *res)
211 211 {
212 212 const char *sid_prefix;
213 213
214 214 if (kidmap_getsidbygid(zone, id, &sid_prefix, &res->ks_rid)
215 215 != IDMAP_SUCCESS)
216 216 return (-1);
217 217
218 218 res->ks_domain = ksid_lookupdomain(sid_prefix);
219 219
220 220 res->ks_id = id;
221 221
222 222 return (0);
223 223 }
224 224
225 225 credsid_t *
226 226 kcrsid_alloc(void)
227 227 {
228 228 credsid_t *kcr = kmem_zalloc(sizeof (*kcr), KM_SLEEP);
229 229 kcr->kr_ref = 1;
230 230 return (kcr);
231 231 }
232 232
233 233 /*
234 234 * Returns a credsid_t with a refcount of 1.
235 235 */
236 236 static credsid_t *
237 237 kcrsid_dup(credsid_t *org)
238 238 {
239 239 credsid_t *new;
240 240 ksid_index_t ki;
241 241
242 242 if (org == NULL)
243 243 return (kcrsid_alloc());
244 244 if (org->kr_ref == 1)
245 245 return (org);
246 246 new = kcrsid_alloc();
247 247
248 248 /* Copy, then update reference counts */
249 249 *new = *org;
250 250 new->kr_ref = 1;
251 251 for (ki = 0; ki < KSID_COUNT; ki++)
252 252 ksid_hold(&new->kr_sidx[ki]);
253 253
↓ open down ↓ |
130 lines elided |
↑ open up ↑ |
254 254 if (new->kr_sidlist != NULL)
255 255 ksidlist_hold(new->kr_sidlist);
256 256
257 257 kcrsid_rele(org);
258 258 return (new);
259 259 }
260 260
261 261 void
262 262 kcrsid_hold(credsid_t *kcr)
263 263 {
264 - atomic_add_32(&kcr->kr_ref, 1);
264 + atomic_inc_32(&kcr->kr_ref);
265 265 }
266 266
267 267 void
268 268 kcrsid_rele(credsid_t *kcr)
269 269 {
270 - if (atomic_add_32_nv(&kcr->kr_ref, -1) == 0) {
270 + if (atomic_dec_32_nv(&kcr->kr_ref) == 0) {
271 271 ksid_index_t i;
272 272
273 273 for (i = 0; i < KSID_COUNT; i++)
274 274 ksid_rele(&kcr->kr_sidx[i]);
275 275
276 276 if (kcr->kr_sidlist != NULL)
277 277 ksidlist_rele(kcr->kr_sidlist);
278 278
279 279 kmem_free(kcr, sizeof (*kcr));
280 280 }
281 281 }
282 282
283 283 /*
284 284 * Copy the SID credential into a previously allocated piece of memory.
285 285 */
286 286 void
287 287 kcrsidcopy_to(const credsid_t *okcr, credsid_t *nkcr)
288 288 {
289 289 int i;
290 290
291 291 ASSERT(nkcr->kr_ref == 1);
292 292
293 293 if (okcr == NULL)
294 294 return;
295 295 *nkcr = *okcr;
296 296 for (i = 0; i < KSID_COUNT; i++)
297 297 ksid_hold(&nkcr->kr_sidx[i]);
298 298 if (nkcr->kr_sidlist != NULL)
299 299 ksidlist_hold(nkcr->kr_sidlist);
300 300 nkcr->kr_ref = 1;
301 301 }
302 302
303 303 static int
304 304 kcrsid_sidcount(const credsid_t *kcr)
305 305 {
306 306 int cnt = 0;
307 307 int i;
308 308
309 309 if (kcr == NULL)
310 310 return (0);
311 311
312 312 for (i = 0; i < KSID_COUNT; i++)
313 313 if (kcr->kr_sidx[i].ks_domain != NULL)
314 314 cnt++;
315 315
316 316 if (kcr->kr_sidlist != NULL)
317 317 cnt += kcr->kr_sidlist->ksl_nsid;
318 318 return (cnt);
319 319 }
320 320
321 321 /*
322 322 * Argument needs to be a ksid_t with a properly held ks_domain reference.
323 323 */
324 324 credsid_t *
325 325 kcrsid_setsid(credsid_t *okcr, ksid_t *ksp, ksid_index_t i)
326 326 {
327 327 int ocnt = kcrsid_sidcount(okcr);
328 328 credsid_t *nkcr;
329 329
330 330 /*
331 331 * Unset the particular ksid; if there are no other SIDs or if this
332 332 * is the last SID, remove the auxilary data structure.
333 333 */
334 334 if (ksp == NULL) {
335 335 if (ocnt == 0 ||
336 336 (ocnt == 1 && okcr->kr_sidx[i].ks_domain != NULL)) {
337 337 if (okcr != NULL)
338 338 kcrsid_rele(okcr);
339 339 return (NULL);
340 340 }
341 341 }
342 342 nkcr = kcrsid_dup(okcr);
343 343 ksid_rele(&nkcr->kr_sidx[i]);
344 344 if (ksp == NULL)
345 345 bzero(&nkcr->kr_sidx[i], sizeof (ksid_t));
346 346 else
347 347 nkcr->kr_sidx[i] = *ksp;
348 348
349 349 return (nkcr);
350 350 }
351 351
352 352 /*
353 353 * Argument needs to be a ksidlist_t with properly held ks_domain references
354 354 * and a reference count taking the new reference into account.
355 355 */
356 356 credsid_t *
357 357 kcrsid_setsidlist(credsid_t *okcr, ksidlist_t *ksl)
358 358 {
359 359 int ocnt = kcrsid_sidcount(okcr);
360 360 credsid_t *nkcr;
361 361
362 362 /*
363 363 * Unset the sidlist; if there are no further SIDs, remove the
364 364 * auxilary data structure.
365 365 */
366 366 if (ksl == NULL) {
367 367 if (ocnt == 0 || (okcr->kr_sidlist != NULL &&
368 368 ocnt == okcr->kr_sidlist->ksl_nsid)) {
369 369 if (okcr != NULL)
370 370 kcrsid_rele(okcr);
371 371 return (NULL);
372 372 }
373 373 }
374 374 nkcr = kcrsid_dup(okcr);
375 375 if (nkcr->kr_sidlist != NULL)
376 376 ksidlist_rele(nkcr->kr_sidlist);
377 377
378 378 nkcr->kr_sidlist = ksl;
379 379 return (nkcr);
380 380 }
381 381
382 382 ksidlist_t *
383 383 kcrsid_gidstosids(zone_t *zone, int ngrp, gid_t *grp)
384 384 {
385 385 int i;
386 386 ksidlist_t *list;
387 387 int cnt;
388 388
389 389 if (ngrp == 0)
390 390 return (NULL);
391 391
392 392 cnt = 0;
393 393 list = kmem_zalloc(KSIDLIST_MEM(ngrp), KM_SLEEP);
394 394
395 395 list->ksl_nsid = ngrp;
396 396 list->ksl_ref = 1;
397 397
398 398 for (i = 0; i < ngrp; i++) {
399 399 if (grp[i] > MAXUID) {
400 400 list->ksl_neid++;
401 401 if (ksid_lookupbygid(zone,
402 402 grp[i], &list->ksl_sids[i]) != 0) {
403 403 while (--i >= 0)
404 404 ksid_rele(&list->ksl_sids[i]);
405 405 cnt = 0;
406 406 break;
407 407 }
408 408 cnt++;
409 409 } else {
410 410 list->ksl_sids[i].ks_id = grp[i];
411 411 }
412 412 }
413 413 if (cnt == 0) {
414 414 kmem_free(list, KSIDLIST_MEM(ngrp));
415 415 return (NULL);
416 416 }
417 417 return (list);
418 418 }
↓ open down ↓ |
138 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX