diff options
Diffstat (limited to 'security/selinux/ss/sidtab.c')
-rw-r--r-- | security/selinux/ss/sidtab.c | 76 |
1 files changed, 26 insertions, 50 deletions
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index 4a516ff4bcde..a81ded104129 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c | |||
@@ -14,10 +14,6 @@ | |||
14 | #define SIDTAB_HASH(sid) \ | 14 | #define SIDTAB_HASH(sid) \ |
15 | (sid & SIDTAB_HASH_MASK) | 15 | (sid & SIDTAB_HASH_MASK) |
16 | 16 | ||
17 | #define INIT_SIDTAB_LOCK(s) spin_lock_init(&s->lock) | ||
18 | #define SIDTAB_LOCK(s, x) spin_lock_irqsave(&s->lock, x) | ||
19 | #define SIDTAB_UNLOCK(s, x) spin_unlock_irqrestore(&s->lock, x) | ||
20 | |||
21 | int sidtab_init(struct sidtab *s) | 17 | int sidtab_init(struct sidtab *s) |
22 | { | 18 | { |
23 | int i; | 19 | int i; |
@@ -30,7 +26,7 @@ int sidtab_init(struct sidtab *s) | |||
30 | s->nel = 0; | 26 | s->nel = 0; |
31 | s->next_sid = 1; | 27 | s->next_sid = 1; |
32 | s->shutdown = 0; | 28 | s->shutdown = 0; |
33 | INIT_SIDTAB_LOCK(s); | 29 | spin_lock_init(&s->lock); |
34 | return 0; | 30 | return 0; |
35 | } | 31 | } |
36 | 32 | ||
@@ -86,7 +82,7 @@ out: | |||
86 | return rc; | 82 | return rc; |
87 | } | 83 | } |
88 | 84 | ||
89 | struct context *sidtab_search(struct sidtab *s, u32 sid) | 85 | static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force) |
90 | { | 86 | { |
91 | int hvalue; | 87 | int hvalue; |
92 | struct sidtab_node *cur; | 88 | struct sidtab_node *cur; |
@@ -99,7 +95,10 @@ struct context *sidtab_search(struct sidtab *s, u32 sid) | |||
99 | while (cur != NULL && sid > cur->sid) | 95 | while (cur != NULL && sid > cur->sid) |
100 | cur = cur->next; | 96 | cur = cur->next; |
101 | 97 | ||
102 | if (cur == NULL || sid != cur->sid) { | 98 | if (force && cur && sid == cur->sid && cur->context.len) |
99 | return &cur->context; | ||
100 | |||
101 | if (cur == NULL || sid != cur->sid || cur->context.len) { | ||
103 | /* Remap invalid SIDs to the unlabeled SID. */ | 102 | /* Remap invalid SIDs to the unlabeled SID. */ |
104 | sid = SECINITSID_UNLABELED; | 103 | sid = SECINITSID_UNLABELED; |
105 | hvalue = SIDTAB_HASH(sid); | 104 | hvalue = SIDTAB_HASH(sid); |
@@ -113,6 +112,16 @@ struct context *sidtab_search(struct sidtab *s, u32 sid) | |||
113 | return &cur->context; | 112 | return &cur->context; |
114 | } | 113 | } |
115 | 114 | ||
115 | struct context *sidtab_search(struct sidtab *s, u32 sid) | ||
116 | { | ||
117 | return sidtab_search_core(s, sid, 0); | ||
118 | } | ||
119 | |||
120 | struct context *sidtab_search_force(struct sidtab *s, u32 sid) | ||
121 | { | ||
122 | return sidtab_search_core(s, sid, 1); | ||
123 | } | ||
124 | |||
116 | int sidtab_map(struct sidtab *s, | 125 | int sidtab_map(struct sidtab *s, |
117 | int (*apply) (u32 sid, | 126 | int (*apply) (u32 sid, |
118 | struct context *context, | 127 | struct context *context, |
@@ -138,43 +147,6 @@ out: | |||
138 | return rc; | 147 | return rc; |
139 | } | 148 | } |
140 | 149 | ||
141 | void sidtab_map_remove_on_error(struct sidtab *s, | ||
142 | int (*apply) (u32 sid, | ||
143 | struct context *context, | ||
144 | void *args), | ||
145 | void *args) | ||
146 | { | ||
147 | int i, ret; | ||
148 | struct sidtab_node *last, *cur, *temp; | ||
149 | |||
150 | if (!s) | ||
151 | return; | ||
152 | |||
153 | for (i = 0; i < SIDTAB_SIZE; i++) { | ||
154 | last = NULL; | ||
155 | cur = s->htable[i]; | ||
156 | while (cur != NULL) { | ||
157 | ret = apply(cur->sid, &cur->context, args); | ||
158 | if (ret) { | ||
159 | if (last) | ||
160 | last->next = cur->next; | ||
161 | else | ||
162 | s->htable[i] = cur->next; | ||
163 | temp = cur; | ||
164 | cur = cur->next; | ||
165 | context_destroy(&temp->context); | ||
166 | kfree(temp); | ||
167 | s->nel--; | ||
168 | } else { | ||
169 | last = cur; | ||
170 | cur = cur->next; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | return; | ||
176 | } | ||
177 | |||
178 | static inline u32 sidtab_search_context(struct sidtab *s, | 150 | static inline u32 sidtab_search_context(struct sidtab *s, |
179 | struct context *context) | 151 | struct context *context) |
180 | { | 152 | { |
@@ -204,7 +176,7 @@ int sidtab_context_to_sid(struct sidtab *s, | |||
204 | 176 | ||
205 | sid = sidtab_search_context(s, context); | 177 | sid = sidtab_search_context(s, context); |
206 | if (!sid) { | 178 | if (!sid) { |
207 | SIDTAB_LOCK(s, flags); | 179 | spin_lock_irqsave(&s->lock, flags); |
208 | /* Rescan now that we hold the lock. */ | 180 | /* Rescan now that we hold the lock. */ |
209 | sid = sidtab_search_context(s, context); | 181 | sid = sidtab_search_context(s, context); |
210 | if (sid) | 182 | if (sid) |
@@ -215,11 +187,15 @@ int sidtab_context_to_sid(struct sidtab *s, | |||
215 | goto unlock_out; | 187 | goto unlock_out; |
216 | } | 188 | } |
217 | sid = s->next_sid++; | 189 | sid = s->next_sid++; |
190 | if (context->len) | ||
191 | printk(KERN_INFO | ||
192 | "SELinux: Context %s is not valid (left unmapped).\n", | ||
193 | context->str); | ||
218 | ret = sidtab_insert(s, sid, context); | 194 | ret = sidtab_insert(s, sid, context); |
219 | if (ret) | 195 | if (ret) |
220 | s->next_sid--; | 196 | s->next_sid--; |
221 | unlock_out: | 197 | unlock_out: |
222 | SIDTAB_UNLOCK(s, flags); | 198 | spin_unlock_irqrestore(&s->lock, flags); |
223 | } | 199 | } |
224 | 200 | ||
225 | if (ret) | 201 | if (ret) |
@@ -284,19 +260,19 @@ void sidtab_set(struct sidtab *dst, struct sidtab *src) | |||
284 | { | 260 | { |
285 | unsigned long flags; | 261 | unsigned long flags; |
286 | 262 | ||
287 | SIDTAB_LOCK(src, flags); | 263 | spin_lock_irqsave(&src->lock, flags); |
288 | dst->htable = src->htable; | 264 | dst->htable = src->htable; |
289 | dst->nel = src->nel; | 265 | dst->nel = src->nel; |
290 | dst->next_sid = src->next_sid; | 266 | dst->next_sid = src->next_sid; |
291 | dst->shutdown = 0; | 267 | dst->shutdown = 0; |
292 | SIDTAB_UNLOCK(src, flags); | 268 | spin_unlock_irqrestore(&src->lock, flags); |
293 | } | 269 | } |
294 | 270 | ||
295 | void sidtab_shutdown(struct sidtab *s) | 271 | void sidtab_shutdown(struct sidtab *s) |
296 | { | 272 | { |
297 | unsigned long flags; | 273 | unsigned long flags; |
298 | 274 | ||
299 | SIDTAB_LOCK(s, flags); | 275 | spin_lock_irqsave(&s->lock, flags); |
300 | s->shutdown = 1; | 276 | s->shutdown = 1; |
301 | SIDTAB_UNLOCK(s, flags); | 277 | spin_unlock_irqrestore(&s->lock, flags); |
302 | } | 278 | } |