1616#include "smack.h"
1717
1818struct smack_known smack_known_huh = {
19- .smk_next = NULL ,
2019 .smk_known = "?" ,
2120 .smk_secid = 2 ,
2221 .smk_cipso = NULL ,
2322};
2423
2524struct smack_known smack_known_hat = {
26- .smk_next = & smack_known_huh ,
2725 .smk_known = "^" ,
2826 .smk_secid = 3 ,
2927 .smk_cipso = NULL ,
3028};
3129
3230struct smack_known smack_known_star = {
33- .smk_next = & smack_known_hat ,
3431 .smk_known = "*" ,
3532 .smk_secid = 4 ,
3633 .smk_cipso = NULL ,
3734};
3835
3936struct smack_known smack_known_floor = {
40- .smk_next = & smack_known_star ,
4137 .smk_known = "_" ,
4238 .smk_secid = 5 ,
4339 .smk_cipso = NULL ,
4440};
4541
4642struct smack_known smack_known_invalid = {
47- .smk_next = & smack_known_floor ,
4843 .smk_known = "" ,
4944 .smk_secid = 6 ,
5045 .smk_cipso = NULL ,
5146};
5247
5348struct smack_known smack_known_web = {
54- .smk_next = & smack_known_invalid ,
5549 .smk_known = "@" ,
5650 .smk_secid = 7 ,
5751 .smk_cipso = NULL ,
5852};
5953
60- struct smack_known * smack_known = & smack_known_web ;
54+ LIST_HEAD ( smack_known_list ) ;
6155
6256/*
6357 * The initial value needs to be bigger than any of the
@@ -87,7 +81,6 @@ static u32 smack_next_secid = 10;
8781int smk_access (char * subject_label , char * object_label , int request )
8882{
8983 u32 may = MAY_NOT ;
90- struct smk_list_entry * sp ;
9184 struct smack_rule * srp ;
9285
9386 /*
@@ -139,9 +132,8 @@ int smk_access(char *subject_label, char *object_label, int request)
139132 * access (e.g. read is included in readwrite) it's
140133 * good.
141134 */
142- for (sp = smack_list ; sp != NULL ; sp = sp -> smk_next ) {
143- srp = & sp -> smk_rule ;
144-
135+ rcu_read_lock ();
136+ list_for_each_entry_rcu (srp , & smack_rule_list , list ) {
145137 if (srp -> smk_subject == subject_label ||
146138 strcmp (srp -> smk_subject , subject_label ) == 0 ) {
147139 if (srp -> smk_object == object_label ||
@@ -151,6 +143,7 @@ int smk_access(char *subject_label, char *object_label, int request)
151143 }
152144 }
153145 }
146+ rcu_read_unlock ();
154147 /*
155148 * This is a bit map operation.
156149 */
@@ -228,14 +221,17 @@ struct smack_known *smk_import_entry(const char *string, int len)
228221
229222 mutex_lock (& smack_known_lock );
230223
231- for (skp = smack_known ; skp != NULL ; skp = skp -> smk_next )
232- if (strncmp (skp -> smk_known , smack , SMK_MAXLEN ) == 0 )
224+ found = 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 ;
233228 break ;
229+ }
230+ }
234231
235- if (skp == NULL ) {
232+ if (found == 0 ) {
236233 skp = kzalloc (sizeof (struct smack_known ), GFP_KERNEL );
237234 if (skp != NULL ) {
238- skp -> smk_next = smack_known ;
239235 strncpy (skp -> smk_known , smack , SMK_MAXLEN );
240236 skp -> smk_secid = smack_next_secid ++ ;
241237 skp -> smk_cipso = NULL ;
@@ -244,8 +240,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
244240 * Make sure that the entry is actually
245241 * filled before putting it on the list.
246242 */
247- smp_mb ();
248- smack_known = skp ;
243+ list_add_rcu (& skp -> list , & smack_known_list );
249244 }
250245 }
251246
@@ -283,14 +278,19 @@ char *smack_from_secid(const u32 secid)
283278{
284279 struct smack_known * skp ;
285280
286- for (skp = smack_known ; skp != NULL ; skp = skp -> smk_next )
287- if (skp -> smk_secid == secid )
281+ rcu_read_lock ();
282+ list_for_each_entry_rcu (skp , & smack_known_list , list ) {
283+ if (skp -> smk_secid == secid ) {
284+ rcu_read_unlock ();
288285 return skp -> smk_known ;
286+ }
287+ }
289288
290289 /*
291290 * If we got this far someone asked for the translation
292291 * of a secid that is not on the list.
293292 */
293+ rcu_read_unlock ();
294294 return smack_known_invalid .smk_known ;
295295}
296296
@@ -305,9 +305,14 @@ u32 smack_to_secid(const char *smack)
305305{
306306 struct smack_known * skp ;
307307
308- for (skp = smack_known ; skp != NULL ; skp = skp -> smk_next )
309- if (strncmp (skp -> smk_known , smack , SMK_MAXLEN ) == 0 )
308+ rcu_read_lock ();
309+ list_for_each_entry_rcu (skp , & smack_known_list , list ) {
310+ if (strncmp (skp -> smk_known , smack , SMK_MAXLEN ) == 0 ) {
311+ rcu_read_unlock ();
310312 return skp -> smk_secid ;
313+ }
314+ }
315+ rcu_read_unlock ();
311316 return 0 ;
312317}
313318
@@ -332,7 +337,8 @@ void smack_from_cipso(u32 level, char *cp, char *result)
332337 struct smack_known * kp ;
333338 char * final = NULL ;
334339
335- for (kp = smack_known ; final == NULL && kp != NULL ; kp = kp -> smk_next ) {
340+ rcu_read_lock ();
341+ list_for_each_entry (kp , & smack_known_list , list ) {
336342 if (kp -> smk_cipso == NULL )
337343 continue ;
338344
@@ -344,6 +350,7 @@ void smack_from_cipso(u32 level, char *cp, char *result)
344350
345351 spin_unlock_bh (& kp -> smk_cipsolock );
346352 }
353+ rcu_read_unlock ();
347354 if (final == NULL )
348355 final = smack_known_huh .smk_known ;
349356 strncpy (result , final , SMK_MAXLEN );
@@ -360,13 +367,19 @@ void smack_from_cipso(u32 level, char *cp, char *result)
360367int smack_to_cipso (const char * smack , struct smack_cipso * cp )
361368{
362369 struct smack_known * kp ;
370+ int found = 0 ;
363371
364- for (kp = smack_known ; kp != NULL ; kp = kp -> smk_next )
372+ rcu_read_lock ();
373+ list_for_each_entry_rcu (kp , & smack_known_list , list ) {
365374 if (kp -> smk_known == smack ||
366- strcmp (kp -> smk_known , smack ) == 0 )
375+ strcmp (kp -> smk_known , smack ) == 0 ) {
376+ found = 1 ;
367377 break ;
378+ }
379+ }
380+ rcu_read_unlock ();
368381
369- if (kp == NULL || kp -> smk_cipso == NULL )
382+ if (found == 0 || kp -> smk_cipso == NULL )
370383 return - ENOENT ;
371384
372385 memcpy (cp , kp -> smk_cipso , sizeof (struct smack_cipso ));
0 commit comments