aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_access.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r--security/smack/smack_access.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index cfa19ca125e3..ac0a2707f6d4 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -16,48 +16,42 @@
16#include "smack.h" 16#include "smack.h"
17 17
18struct smack_known smack_known_huh = { 18struct smack_known smack_known_huh = {
19 .smk_next = NULL,
20 .smk_known = "?", 19 .smk_known = "?",
21 .smk_secid = 2, 20 .smk_secid = 2,
22 .smk_cipso = NULL, 21 .smk_cipso = NULL,
23}; 22};
24 23
25struct smack_known smack_known_hat = { 24struct smack_known smack_known_hat = {
26 .smk_next = &smack_known_huh,
27 .smk_known = "^", 25 .smk_known = "^",
28 .smk_secid = 3, 26 .smk_secid = 3,
29 .smk_cipso = NULL, 27 .smk_cipso = NULL,
30}; 28};
31 29
32struct smack_known smack_known_star = { 30struct smack_known smack_known_star = {
33 .smk_next = &smack_known_hat,
34 .smk_known = "*", 31 .smk_known = "*",
35 .smk_secid = 4, 32 .smk_secid = 4,
36 .smk_cipso = NULL, 33 .smk_cipso = NULL,
37}; 34};
38 35
39struct smack_known smack_known_floor = { 36struct smack_known smack_known_floor = {
40 .smk_next = &smack_known_star,
41 .smk_known = "_", 37 .smk_known = "_",
42 .smk_secid = 5, 38 .smk_secid = 5,
43 .smk_cipso = NULL, 39 .smk_cipso = NULL,
44}; 40};
45 41
46struct smack_known smack_known_invalid = { 42struct smack_known smack_known_invalid = {
47 .smk_next = &smack_known_floor,
48 .smk_known = "", 43 .smk_known = "",
49 .smk_secid = 6, 44 .smk_secid = 6,
50 .smk_cipso = NULL, 45 .smk_cipso = NULL,
51}; 46};
52 47
53struct smack_known smack_known_web = { 48struct smack_known smack_known_web = {
54 .smk_next = &smack_known_invalid,
55 .smk_known = "@", 49 .smk_known = "@",
56 .smk_secid = 7, 50 .smk_secid = 7,
57 .smk_cipso = NULL, 51 .smk_cipso = NULL,
58}; 52};
59 53
60struct smack_known *smack_known = &smack_known_web; 54LIST_HEAD(smack_known_list);
61 55
62/* 56/*
63 * The initial value needs to be bigger than any of the 57 * The initial value needs to be bigger than any of the
@@ -87,7 +81,6 @@ static u32 smack_next_secid = 10;
87int smk_access(char *subject_label, char *object_label, int request) 81int smk_access(char *subject_label, char *object_label, int request)
88{ 82{
89 u32 may = MAY_NOT; 83 u32 may = MAY_NOT;
90 struct smk_list_entry *sp;
91 struct smack_rule *srp; 84 struct smack_rule *srp;
92 85
93 /* 86 /*
@@ -139,9 +132,8 @@ int smk_access(char *subject_label, char *object_label, int request)
139 * access (e.g. read is included in readwrite) it's 132 * access (e.g. read is included in readwrite) it's
140 * good. 133 * good.
141 */ 134 */
142 for (sp = smack_list; sp != NULL; sp = sp->smk_next) { 135 rcu_read_lock();
143 srp = &sp->smk_rule; 136 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
144
145 if (srp->smk_subject == subject_label || 137 if (srp->smk_subject == subject_label ||
146 strcmp(srp->smk_subject, subject_label) == 0) { 138 strcmp(srp->smk_subject, subject_label) == 0) {
147 if (srp->smk_object == object_label || 139 if (srp->smk_object == object_label ||
@@ -151,6 +143,7 @@ int smk_access(char *subject_label, char *object_label, int request)
151 } 143 }
152 } 144 }
153 } 145 }
146 rcu_read_unlock();
154 /* 147 /*
155 * This is a bit map operation. 148 * This is a bit map operation.
156 */ 149 */
@@ -228,14 +221,17 @@ struct smack_known *smk_import_entry(const char *string, int len)
228 221
229 mutex_lock(&smack_known_lock); 222 mutex_lock(&smack_known_lock);
230 223
231 for (skp = smack_known; skp != NULL; skp = skp->smk_next) 224 found = 0;
232 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) 225 list_for_each_entry_rcu(skp, &smack_known_list, list) {
226 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
227 found = 1;
233 break; 228 break;
229 }
230 }
234 231
235 if (skp == NULL) { 232 if (found == 0) {
236 skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL); 233 skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL);
237 if (skp != NULL) { 234 if (skp != NULL) {
238 skp->smk_next = smack_known;
239 strncpy(skp->smk_known, smack, SMK_MAXLEN); 235 strncpy(skp->smk_known, smack, SMK_MAXLEN);
240 skp->smk_secid = smack_next_secid++; 236 skp->smk_secid = smack_next_secid++;
241 skp->smk_cipso = NULL; 237 skp->smk_cipso = NULL;
@@ -244,8 +240,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
244 * Make sure that the entry is actually 240 * Make sure that the entry is actually
245 * filled before putting it on the list. 241 * filled before putting it on the list.
246 */ 242 */
247 smp_mb(); 243 list_add_rcu(&skp->list, &smack_known_list);
248 smack_known = skp;
249 } 244 }
250 } 245 }
251 246
@@ -266,6 +261,9 @@ char *smk_import(const char *string, int len)
266{ 261{
267 struct smack_known *skp; 262 struct smack_known *skp;
268 263
264 /* labels cannot begin with a '-' */
265 if (string[0] == '-')
266 return NULL;
269 skp = smk_import_entry(string, len); 267 skp = smk_import_entry(string, len);
270 if (skp == NULL) 268 if (skp == NULL)
271 return NULL; 269 return NULL;
@@ -283,14 +281,19 @@ char *smack_from_secid(const u32 secid)
283{ 281{
284 struct smack_known *skp; 282 struct smack_known *skp;
285 283
286 for (skp = smack_known; skp != NULL; skp = skp->smk_next) 284 rcu_read_lock();
287 if (skp->smk_secid == secid) 285 list_for_each_entry_rcu(skp, &smack_known_list, list) {
286 if (skp->smk_secid == secid) {
287 rcu_read_unlock();
288 return skp->smk_known; 288 return skp->smk_known;
289 }
290 }
289 291
290 /* 292 /*
291 * If we got this far someone asked for the translation 293 * If we got this far someone asked for the translation
292 * of a secid that is not on the list. 294 * of a secid that is not on the list.
293 */ 295 */
296 rcu_read_unlock();
294 return smack_known_invalid.smk_known; 297 return smack_known_invalid.smk_known;
295} 298}
296 299
@@ -305,9 +308,14 @@ u32 smack_to_secid(const char *smack)
305{ 308{
306 struct smack_known *skp; 309 struct smack_known *skp;
307 310
308 for (skp = smack_known; skp != NULL; skp = skp->smk_next) 311 rcu_read_lock();
309 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) 312 list_for_each_entry_rcu(skp, &smack_known_list, list) {
313 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
314 rcu_read_unlock();
310 return skp->smk_secid; 315 return skp->smk_secid;
316 }
317 }
318 rcu_read_unlock();
311 return 0; 319 return 0;
312} 320}
313 321
@@ -332,7 +340,8 @@ void smack_from_cipso(u32 level, char *cp, char *result)
332 struct smack_known *kp; 340 struct smack_known *kp;
333 char *final = NULL; 341 char *final = NULL;
334 342
335 for (kp = smack_known; final == NULL && kp != NULL; kp = kp->smk_next) { 343 rcu_read_lock();
344 list_for_each_entry(kp, &smack_known_list, list) {
336 if (kp->smk_cipso == NULL) 345 if (kp->smk_cipso == NULL)
337 continue; 346 continue;
338 347
@@ -344,6 +353,7 @@ void smack_from_cipso(u32 level, char *cp, char *result)
344 353
345 spin_unlock_bh(&kp->smk_cipsolock); 354 spin_unlock_bh(&kp->smk_cipsolock);
346 } 355 }
356 rcu_read_unlock();
347 if (final == NULL) 357 if (final == NULL)
348 final = smack_known_huh.smk_known; 358 final = smack_known_huh.smk_known;
349 strncpy(result, final, SMK_MAXLEN); 359 strncpy(result, final, SMK_MAXLEN);
@@ -360,13 +370,19 @@ void smack_from_cipso(u32 level, char *cp, char *result)
360int smack_to_cipso(const char *smack, struct smack_cipso *cp) 370int smack_to_cipso(const char *smack, struct smack_cipso *cp)
361{ 371{
362 struct smack_known *kp; 372 struct smack_known *kp;
373 int found = 0;
363 374
364 for (kp = smack_known; kp != NULL; kp = kp->smk_next) 375 rcu_read_lock();
376 list_for_each_entry_rcu(kp, &smack_known_list, list) {
365 if (kp->smk_known == smack || 377 if (kp->smk_known == smack ||
366 strcmp(kp->smk_known, smack) == 0) 378 strcmp(kp->smk_known, smack) == 0) {
379 found = 1;
367 break; 380 break;
381 }
382 }
383 rcu_read_unlock();
368 384
369 if (kp == NULL || kp->smk_cipso == NULL) 385 if (found == 0 || kp->smk_cipso == NULL)
370 return -ENOENT; 386 return -ENOENT;
371 387
372 memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso)); 388 memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso));