aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/sidtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/sidtab.c')
-rw-r--r--security/selinux/ss/sidtab.c76
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
21int sidtab_init(struct sidtab *s) 17int 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
89struct context *sidtab_search(struct sidtab *s, u32 sid) 85static 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
115struct context *sidtab_search(struct sidtab *s, u32 sid)
116{
117 return sidtab_search_core(s, sid, 0);
118}
119
120struct context *sidtab_search_force(struct sidtab *s, u32 sid)
121{
122 return sidtab_search_core(s, sid, 1);
123}
124
116int sidtab_map(struct sidtab *s, 125int 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
141void 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
178static inline u32 sidtab_search_context(struct sidtab *s, 150static 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--;
221unlock_out: 197unlock_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
295void sidtab_shutdown(struct sidtab *s) 271void 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}