aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/conditional.c6
-rw-r--r--security/selinux/ss/mls.c25
-rw-r--r--security/selinux/ss/policydb.c701
-rw-r--r--security/selinux/ss/policydb.h19
-rw-r--r--security/selinux/ss/services.c425
-rw-r--r--security/selinux/ss/sidtab.c39
-rw-r--r--security/selinux/ss/sidtab.h2
7 files changed, 626 insertions, 591 deletions
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 655fe1c6cc69..c3f845cbcd48 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -193,6 +193,7 @@ int cond_index_bool(void *key, void *datum, void *datap)
193{ 193{
194 struct policydb *p; 194 struct policydb *p;
195 struct cond_bool_datum *booldatum; 195 struct cond_bool_datum *booldatum;
196 struct flex_array *fa;
196 197
197 booldatum = datum; 198 booldatum = datum;
198 p = datap; 199 p = datap;
@@ -200,7 +201,10 @@ int cond_index_bool(void *key, void *datum, void *datap)
200 if (!booldatum->value || booldatum->value > p->p_bools.nprim) 201 if (!booldatum->value || booldatum->value > p->p_bools.nprim)
201 return -EINVAL; 202 return -EINVAL;
202 203
203 p->p_bool_val_to_name[booldatum->value - 1] = key; 204 fa = p->sym_val_to_name[SYM_BOOLS];
205 if (flex_array_put_ptr(fa, booldatum->value - 1, key,
206 GFP_KERNEL | __GFP_ZERO))
207 BUG();
204 p->bool_val_to_struct[booldatum->value - 1] = booldatum; 208 p->bool_val_to_struct[booldatum->value - 1] = booldatum;
205 209
206 return 0; 210 return 0;
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b4eff7a60c50..1ef8e4e89880 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -45,7 +45,7 @@ int mls_compute_context_len(struct context *context)
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
46 for (l = 0; l < 2; l++) { 46 for (l = 0; l < 2; l++) {
47 int index_sens = context->range.level[l].sens; 47 int index_sens = context->range.level[l].sens;
48 len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); 48 len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
49 49
50 /* categories */ 50 /* categories */
51 head = -2; 51 head = -2;
@@ -55,17 +55,17 @@ int mls_compute_context_len(struct context *context)
55 if (i - prev > 1) { 55 if (i - prev > 1) {
56 /* one or more negative bits are skipped */ 56 /* one or more negative bits are skipped */
57 if (head != prev) { 57 if (head != prev) {
58 nm = policydb.p_cat_val_to_name[prev]; 58 nm = sym_name(&policydb, SYM_CATS, prev);
59 len += strlen(nm) + 1; 59 len += strlen(nm) + 1;
60 } 60 }
61 nm = policydb.p_cat_val_to_name[i]; 61 nm = sym_name(&policydb, SYM_CATS, i);
62 len += strlen(nm) + 1; 62 len += strlen(nm) + 1;
63 head = i; 63 head = i;
64 } 64 }
65 prev = i; 65 prev = i;
66 } 66 }
67 if (prev != head) { 67 if (prev != head) {
68 nm = policydb.p_cat_val_to_name[prev]; 68 nm = sym_name(&policydb, SYM_CATS, prev);
69 len += strlen(nm) + 1; 69 len += strlen(nm) + 1;
70 } 70 }
71 if (l == 0) { 71 if (l == 0) {
@@ -102,8 +102,8 @@ void mls_sid_to_context(struct context *context,
102 scontextp++; 102 scontextp++;
103 103
104 for (l = 0; l < 2; l++) { 104 for (l = 0; l < 2; l++) {
105 strcpy(scontextp, 105 strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
106 policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 106 context->range.level[l].sens - 1));
107 scontextp += strlen(scontextp); 107 scontextp += strlen(scontextp);
108 108
109 /* categories */ 109 /* categories */
@@ -118,7 +118,7 @@ void mls_sid_to_context(struct context *context,
118 *scontextp++ = '.'; 118 *scontextp++ = '.';
119 else 119 else
120 *scontextp++ = ','; 120 *scontextp++ = ',';
121 nm = policydb.p_cat_val_to_name[prev]; 121 nm = sym_name(&policydb, SYM_CATS, prev);
122 strcpy(scontextp, nm); 122 strcpy(scontextp, nm);
123 scontextp += strlen(nm); 123 scontextp += strlen(nm);
124 } 124 }
@@ -126,7 +126,7 @@ void mls_sid_to_context(struct context *context,
126 *scontextp++ = ':'; 126 *scontextp++ = ':';
127 else 127 else
128 *scontextp++ = ','; 128 *scontextp++ = ',';
129 nm = policydb.p_cat_val_to_name[i]; 129 nm = sym_name(&policydb, SYM_CATS, i);
130 strcpy(scontextp, nm); 130 strcpy(scontextp, nm);
131 scontextp += strlen(nm); 131 scontextp += strlen(nm);
132 head = i; 132 head = i;
@@ -139,7 +139,7 @@ void mls_sid_to_context(struct context *context,
139 *scontextp++ = '.'; 139 *scontextp++ = '.';
140 else 140 else
141 *scontextp++ = ','; 141 *scontextp++ = ',';
142 nm = policydb.p_cat_val_to_name[prev]; 142 nm = sym_name(&policydb, SYM_CATS, prev);
143 strcpy(scontextp, nm); 143 strcpy(scontextp, nm);
144 scontextp += strlen(nm); 144 scontextp += strlen(nm);
145 } 145 }
@@ -166,7 +166,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
166 if (!l->sens || l->sens > p->p_levels.nprim) 166 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0; 167 return 0;
168 levdatum = hashtab_search(p->p_levels.table, 168 levdatum = hashtab_search(p->p_levels.table,
169 p->p_sens_val_to_name[l->sens - 1]); 169 sym_name(p, SYM_LEVELS, l->sens - 1));
170 if (!levdatum) 170 if (!levdatum)
171 return 0; 171 return 0;
172 172
@@ -482,7 +482,8 @@ int mls_convert_context(struct policydb *oldp,
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
484 levdatum = hashtab_search(newp->p_levels.table, 484 levdatum = hashtab_search(newp->p_levels.table,
485 oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); 485 sym_name(oldp, SYM_LEVELS,
486 c->range.level[l].sens - 1));
486 487
487 if (!levdatum) 488 if (!levdatum)
488 return -EINVAL; 489 return -EINVAL;
@@ -493,7 +494,7 @@ int mls_convert_context(struct policydb *oldp,
493 int rc; 494 int rc;
494 495
495 catdatum = hashtab_search(newp->p_cats.table, 496 catdatum = hashtab_search(newp->p_cats.table,
496 oldp->p_cat_val_to_name[i]); 497 sym_name(oldp, SYM_CATS, i));
497 if (!catdatum) 498 if (!catdatum)
498 return -EINVAL; 499 return -EINVAL;
499 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 500 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 94f630d93a5c..be9de3872837 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -148,32 +148,30 @@ static int roles_init(struct policydb *p)
148 int rc; 148 int rc;
149 struct role_datum *role; 149 struct role_datum *role;
150 150
151 rc = -ENOMEM;
151 role = kzalloc(sizeof(*role), GFP_KERNEL); 152 role = kzalloc(sizeof(*role), GFP_KERNEL);
152 if (!role) { 153 if (!role)
153 rc = -ENOMEM;
154 goto out; 154 goto out;
155 } 155
156 rc = -EINVAL;
156 role->value = ++p->p_roles.nprim; 157 role->value = ++p->p_roles.nprim;
157 if (role->value != OBJECT_R_VAL) { 158 if (role->value != OBJECT_R_VAL)
158 rc = -EINVAL; 159 goto out;
159 goto out_free_role; 160
160 } 161 rc = -ENOMEM;
161 key = kstrdup(OBJECT_R, GFP_KERNEL); 162 key = kstrdup(OBJECT_R, GFP_KERNEL);
162 if (!key) { 163 if (!key)
163 rc = -ENOMEM; 164 goto out;
164 goto out_free_role; 165
165 }
166 rc = hashtab_insert(p->p_roles.table, key, role); 166 rc = hashtab_insert(p->p_roles.table, key, role);
167 if (rc) 167 if (rc)
168 goto out_free_key; 168 goto out;
169out:
170 return rc;
171 169
172out_free_key: 170 return 0;
171out:
173 kfree(key); 172 kfree(key);
174out_free_role:
175 kfree(role); 173 kfree(role);
176 goto out; 174 return rc;
177} 175}
178 176
179static u32 rangetr_hash(struct hashtab *h, const void *k) 177static u32 rangetr_hash(struct hashtab *h, const void *k)
@@ -213,35 +211,33 @@ static int policydb_init(struct policydb *p)
213 for (i = 0; i < SYM_NUM; i++) { 211 for (i = 0; i < SYM_NUM; i++) {
214 rc = symtab_init(&p->symtab[i], symtab_sizes[i]); 212 rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
215 if (rc) 213 if (rc)
216 goto out_free_symtab; 214 goto out;
217 } 215 }
218 216
219 rc = avtab_init(&p->te_avtab); 217 rc = avtab_init(&p->te_avtab);
220 if (rc) 218 if (rc)
221 goto out_free_symtab; 219 goto out;
222 220
223 rc = roles_init(p); 221 rc = roles_init(p);
224 if (rc) 222 if (rc)
225 goto out_free_symtab; 223 goto out;
226 224
227 rc = cond_policydb_init(p); 225 rc = cond_policydb_init(p);
228 if (rc) 226 if (rc)
229 goto out_free_symtab; 227 goto out;
230 228
231 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 229 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
232 if (!p->range_tr) 230 if (!p->range_tr)
233 goto out_free_symtab; 231 goto out;
234 232
235 ebitmap_init(&p->policycaps); 233 ebitmap_init(&p->policycaps);
236 ebitmap_init(&p->permissive_map); 234 ebitmap_init(&p->permissive_map);
237 235
236 return 0;
238out: 237out:
239 return rc;
240
241out_free_symtab:
242 for (i = 0; i < SYM_NUM; i++) 238 for (i = 0; i < SYM_NUM; i++)
243 hashtab_destroy(p->symtab[i].table); 239 hashtab_destroy(p->symtab[i].table);
244 goto out; 240 return rc;
245} 241}
246 242
247/* 243/*
@@ -258,12 +254,17 @@ static int common_index(void *key, void *datum, void *datap)
258{ 254{
259 struct policydb *p; 255 struct policydb *p;
260 struct common_datum *comdatum; 256 struct common_datum *comdatum;
257 struct flex_array *fa;
261 258
262 comdatum = datum; 259 comdatum = datum;
263 p = datap; 260 p = datap;
264 if (!comdatum->value || comdatum->value > p->p_commons.nprim) 261 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
265 return -EINVAL; 262 return -EINVAL;
266 p->p_common_val_to_name[comdatum->value - 1] = key; 263
264 fa = p->sym_val_to_name[SYM_COMMONS];
265 if (flex_array_put_ptr(fa, comdatum->value - 1, key,
266 GFP_KERNEL | __GFP_ZERO))
267 BUG();
267 return 0; 268 return 0;
268} 269}
269 270
@@ -271,12 +272,16 @@ static int class_index(void *key, void *datum, void *datap)
271{ 272{
272 struct policydb *p; 273 struct policydb *p;
273 struct class_datum *cladatum; 274 struct class_datum *cladatum;
275 struct flex_array *fa;
274 276
275 cladatum = datum; 277 cladatum = datum;
276 p = datap; 278 p = datap;
277 if (!cladatum->value || cladatum->value > p->p_classes.nprim) 279 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
278 return -EINVAL; 280 return -EINVAL;
279 p->p_class_val_to_name[cladatum->value - 1] = key; 281 fa = p->sym_val_to_name[SYM_CLASSES];
282 if (flex_array_put_ptr(fa, cladatum->value - 1, key,
283 GFP_KERNEL | __GFP_ZERO))
284 BUG();
280 p->class_val_to_struct[cladatum->value - 1] = cladatum; 285 p->class_val_to_struct[cladatum->value - 1] = cladatum;
281 return 0; 286 return 0;
282} 287}
@@ -285,6 +290,7 @@ static int role_index(void *key, void *datum, void *datap)
285{ 290{
286 struct policydb *p; 291 struct policydb *p;
287 struct role_datum *role; 292 struct role_datum *role;
293 struct flex_array *fa;
288 294
289 role = datum; 295 role = datum;
290 p = datap; 296 p = datap;
@@ -292,7 +298,11 @@ static int role_index(void *key, void *datum, void *datap)
292 || role->value > p->p_roles.nprim 298 || role->value > p->p_roles.nprim
293 || role->bounds > p->p_roles.nprim) 299 || role->bounds > p->p_roles.nprim)
294 return -EINVAL; 300 return -EINVAL;
295 p->p_role_val_to_name[role->value - 1] = key; 301
302 fa = p->sym_val_to_name[SYM_ROLES];
303 if (flex_array_put_ptr(fa, role->value - 1, key,
304 GFP_KERNEL | __GFP_ZERO))
305 BUG();
296 p->role_val_to_struct[role->value - 1] = role; 306 p->role_val_to_struct[role->value - 1] = role;
297 return 0; 307 return 0;
298} 308}
@@ -301,6 +311,7 @@ static int type_index(void *key, void *datum, void *datap)
301{ 311{
302 struct policydb *p; 312 struct policydb *p;
303 struct type_datum *typdatum; 313 struct type_datum *typdatum;
314 struct flex_array *fa;
304 315
305 typdatum = datum; 316 typdatum = datum;
306 p = datap; 317 p = datap;
@@ -310,8 +321,15 @@ static int type_index(void *key, void *datum, void *datap)
310 || typdatum->value > p->p_types.nprim 321 || typdatum->value > p->p_types.nprim
311 || typdatum->bounds > p->p_types.nprim) 322 || typdatum->bounds > p->p_types.nprim)
312 return -EINVAL; 323 return -EINVAL;
313 p->p_type_val_to_name[typdatum->value - 1] = key; 324 fa = p->sym_val_to_name[SYM_TYPES];
314 p->type_val_to_struct[typdatum->value - 1] = typdatum; 325 if (flex_array_put_ptr(fa, typdatum->value - 1, key,
326 GFP_KERNEL | __GFP_ZERO))
327 BUG();
328
329 fa = p->type_val_to_struct_array;
330 if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
331 GFP_KERNEL | __GFP_ZERO))
332 BUG();
315 } 333 }
316 334
317 return 0; 335 return 0;
@@ -321,6 +339,7 @@ static int user_index(void *key, void *datum, void *datap)
321{ 339{
322 struct policydb *p; 340 struct policydb *p;
323 struct user_datum *usrdatum; 341 struct user_datum *usrdatum;
342 struct flex_array *fa;
324 343
325 usrdatum = datum; 344 usrdatum = datum;
326 p = datap; 345 p = datap;
@@ -328,7 +347,11 @@ static int user_index(void *key, void *datum, void *datap)
328 || usrdatum->value > p->p_users.nprim 347 || usrdatum->value > p->p_users.nprim
329 || usrdatum->bounds > p->p_users.nprim) 348 || usrdatum->bounds > p->p_users.nprim)
330 return -EINVAL; 349 return -EINVAL;
331 p->p_user_val_to_name[usrdatum->value - 1] = key; 350
351 fa = p->sym_val_to_name[SYM_USERS];
352 if (flex_array_put_ptr(fa, usrdatum->value - 1, key,
353 GFP_KERNEL | __GFP_ZERO))
354 BUG();
332 p->user_val_to_struct[usrdatum->value - 1] = usrdatum; 355 p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
333 return 0; 356 return 0;
334} 357}
@@ -337,6 +360,7 @@ static int sens_index(void *key, void *datum, void *datap)
337{ 360{
338 struct policydb *p; 361 struct policydb *p;
339 struct level_datum *levdatum; 362 struct level_datum *levdatum;
363 struct flex_array *fa;
340 364
341 levdatum = datum; 365 levdatum = datum;
342 p = datap; 366 p = datap;
@@ -345,7 +369,10 @@ static int sens_index(void *key, void *datum, void *datap)
345 if (!levdatum->level->sens || 369 if (!levdatum->level->sens ||
346 levdatum->level->sens > p->p_levels.nprim) 370 levdatum->level->sens > p->p_levels.nprim)
347 return -EINVAL; 371 return -EINVAL;
348 p->p_sens_val_to_name[levdatum->level->sens - 1] = key; 372 fa = p->sym_val_to_name[SYM_LEVELS];
373 if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key,
374 GFP_KERNEL | __GFP_ZERO))
375 BUG();
349 } 376 }
350 377
351 return 0; 378 return 0;
@@ -355,6 +382,7 @@ static int cat_index(void *key, void *datum, void *datap)
355{ 382{
356 struct policydb *p; 383 struct policydb *p;
357 struct cat_datum *catdatum; 384 struct cat_datum *catdatum;
385 struct flex_array *fa;
358 386
359 catdatum = datum; 387 catdatum = datum;
360 p = datap; 388 p = datap;
@@ -362,7 +390,10 @@ static int cat_index(void *key, void *datum, void *datap)
362 if (!catdatum->isalias) { 390 if (!catdatum->isalias) {
363 if (!catdatum->value || catdatum->value > p->p_cats.nprim) 391 if (!catdatum->value || catdatum->value > p->p_cats.nprim)
364 return -EINVAL; 392 return -EINVAL;
365 p->p_cat_val_to_name[catdatum->value - 1] = key; 393 fa = p->sym_val_to_name[SYM_CATS];
394 if (flex_array_put_ptr(fa, catdatum->value - 1, key,
395 GFP_KERNEL | __GFP_ZERO))
396 BUG();
366 } 397 }
367 398
368 return 0; 399 return 0;
@@ -380,47 +411,6 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
380 cat_index, 411 cat_index,
381}; 412};
382 413
383/*
384 * Define the common val_to_name array and the class
385 * val_to_name and val_to_struct arrays in a policy
386 * database structure.
387 *
388 * Caller must clean up upon failure.
389 */
390static int policydb_index_classes(struct policydb *p)
391{
392 int rc;
393
394 p->p_common_val_to_name =
395 kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
396 if (!p->p_common_val_to_name) {
397 rc = -ENOMEM;
398 goto out;
399 }
400
401 rc = hashtab_map(p->p_commons.table, common_index, p);
402 if (rc)
403 goto out;
404
405 p->class_val_to_struct =
406 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
407 if (!p->class_val_to_struct) {
408 rc = -ENOMEM;
409 goto out;
410 }
411
412 p->p_class_val_to_name =
413 kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
414 if (!p->p_class_val_to_name) {
415 rc = -ENOMEM;
416 goto out;
417 }
418
419 rc = hashtab_map(p->p_classes.table, class_index, p);
420out:
421 return rc;
422}
423
424#ifdef DEBUG_HASHES 414#ifdef DEBUG_HASHES
425static void symtab_hash_eval(struct symtab *s) 415static void symtab_hash_eval(struct symtab *s)
426{ 416{
@@ -458,9 +448,9 @@ static inline void rangetr_hash_eval(struct hashtab *h)
458 * 448 *
459 * Caller must clean up on failure. 449 * Caller must clean up on failure.
460 */ 450 */
461static int policydb_index_others(struct policydb *p) 451static int policydb_index(struct policydb *p)
462{ 452{
463 int i, rc = 0; 453 int i, rc;
464 454
465 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 455 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
466 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 456 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
@@ -477,47 +467,63 @@ static int policydb_index_others(struct policydb *p)
477 symtab_hash_eval(p->symtab); 467 symtab_hash_eval(p->symtab);
478#endif 468#endif
479 469
470 rc = -ENOMEM;
471 p->class_val_to_struct =
472 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
473 GFP_KERNEL);
474 if (!p->class_val_to_struct)
475 goto out;
476
477 rc = -ENOMEM;
480 p->role_val_to_struct = 478 p->role_val_to_struct =
481 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), 479 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
482 GFP_KERNEL); 480 GFP_KERNEL);
483 if (!p->role_val_to_struct) { 481 if (!p->role_val_to_struct)
484 rc = -ENOMEM;
485 goto out; 482 goto out;
486 }
487 483
484 rc = -ENOMEM;
488 p->user_val_to_struct = 485 p->user_val_to_struct =
489 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), 486 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
490 GFP_KERNEL); 487 GFP_KERNEL);
491 if (!p->user_val_to_struct) { 488 if (!p->user_val_to_struct)
492 rc = -ENOMEM;
493 goto out; 489 goto out;
494 }
495 490
496 p->type_val_to_struct = 491 /* Yes, I want the sizeof the pointer, not the structure */
497 kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), 492 rc = -ENOMEM;
498 GFP_KERNEL); 493 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
499 if (!p->type_val_to_struct) { 494 p->p_types.nprim,
500 rc = -ENOMEM; 495 GFP_KERNEL | __GFP_ZERO);
496 if (!p->type_val_to_struct_array)
501 goto out; 497 goto out;
502 }
503 498
504 if (cond_init_bool_indexes(p)) { 499 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
505 rc = -ENOMEM; 500 p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO);
501 if (rc)
506 goto out; 502 goto out;
507 }
508 503
509 for (i = SYM_ROLES; i < SYM_NUM; i++) { 504 rc = -ENOMEM;
510 p->sym_val_to_name[i] = 505 if (cond_init_bool_indexes(p))
511 kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); 506 goto out;
512 if (!p->sym_val_to_name[i]) { 507
513 rc = -ENOMEM; 508 for (i = 0; i < SYM_NUM; i++) {
509 rc = -ENOMEM;
510 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
511 p->symtab[i].nprim,
512 GFP_KERNEL | __GFP_ZERO);
513 if (!p->sym_val_to_name[i])
514 goto out; 514 goto out;
515 } 515
516 rc = flex_array_prealloc(p->sym_val_to_name[i],
517 0, p->symtab[i].nprim - 1,
518 GFP_KERNEL | __GFP_ZERO);
519 if (rc)
520 goto out;
521
516 rc = hashtab_map(p->symtab[i].table, index_f[i], p); 522 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
517 if (rc) 523 if (rc)
518 goto out; 524 goto out;
519 } 525 }
520 526 rc = 0;
521out: 527out:
522 return rc; 528 return rc;
523} 529}
@@ -540,9 +546,11 @@ static int common_destroy(void *key, void *datum, void *p)
540 struct common_datum *comdatum; 546 struct common_datum *comdatum;
541 547
542 kfree(key); 548 kfree(key);
543 comdatum = datum; 549 if (datum) {
544 hashtab_map(comdatum->permissions.table, perm_destroy, NULL); 550 comdatum = datum;
545 hashtab_destroy(comdatum->permissions.table); 551 hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
552 hashtab_destroy(comdatum->permissions.table);
553 }
546 kfree(datum); 554 kfree(datum);
547 return 0; 555 return 0;
548} 556}
@@ -554,38 +562,40 @@ static int cls_destroy(void *key, void *datum, void *p)
554 struct constraint_expr *e, *etmp; 562 struct constraint_expr *e, *etmp;
555 563
556 kfree(key); 564 kfree(key);
557 cladatum = datum; 565 if (datum) {
558 hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 566 cladatum = datum;
559 hashtab_destroy(cladatum->permissions.table); 567 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
560 constraint = cladatum->constraints; 568 hashtab_destroy(cladatum->permissions.table);
561 while (constraint) { 569 constraint = cladatum->constraints;
562 e = constraint->expr; 570 while (constraint) {
563 while (e) { 571 e = constraint->expr;
564 ebitmap_destroy(&e->names); 572 while (e) {
565 etmp = e; 573 ebitmap_destroy(&e->names);
566 e = e->next; 574 etmp = e;
567 kfree(etmp); 575 e = e->next;
576 kfree(etmp);
577 }
578 ctemp = constraint;
579 constraint = constraint->next;
580 kfree(ctemp);
568 } 581 }
569 ctemp = constraint; 582
570 constraint = constraint->next; 583 constraint = cladatum->validatetrans;
571 kfree(ctemp); 584 while (constraint) {
572 } 585 e = constraint->expr;
573 586 while (e) {
574 constraint = cladatum->validatetrans; 587 ebitmap_destroy(&e->names);
575 while (constraint) { 588 etmp = e;
576 e = constraint->expr; 589 e = e->next;
577 while (e) { 590 kfree(etmp);
578 ebitmap_destroy(&e->names); 591 }
579 etmp = e; 592 ctemp = constraint;
580 e = e->next; 593 constraint = constraint->next;
581 kfree(etmp); 594 kfree(ctemp);
582 } 595 }
583 ctemp = constraint;
584 constraint = constraint->next;
585 kfree(ctemp);
586 }
587 596
588 kfree(cladatum->comkey); 597 kfree(cladatum->comkey);
598 }
589 kfree(datum); 599 kfree(datum);
590 return 0; 600 return 0;
591} 601}
@@ -595,9 +605,11 @@ static int role_destroy(void *key, void *datum, void *p)
595 struct role_datum *role; 605 struct role_datum *role;
596 606
597 kfree(key); 607 kfree(key);
598 role = datum; 608 if (datum) {
599 ebitmap_destroy(&role->dominates); 609 role = datum;
600 ebitmap_destroy(&role->types); 610 ebitmap_destroy(&role->dominates);
611 ebitmap_destroy(&role->types);
612 }
601 kfree(datum); 613 kfree(datum);
602 return 0; 614 return 0;
603} 615}
@@ -614,11 +626,13 @@ static int user_destroy(void *key, void *datum, void *p)
614 struct user_datum *usrdatum; 626 struct user_datum *usrdatum;
615 627
616 kfree(key); 628 kfree(key);
617 usrdatum = datum; 629 if (datum) {
618 ebitmap_destroy(&usrdatum->roles); 630 usrdatum = datum;
619 ebitmap_destroy(&usrdatum->range.level[0].cat); 631 ebitmap_destroy(&usrdatum->roles);
620 ebitmap_destroy(&usrdatum->range.level[1].cat); 632 ebitmap_destroy(&usrdatum->range.level[0].cat);
621 ebitmap_destroy(&usrdatum->dfltlevel.cat); 633 ebitmap_destroy(&usrdatum->range.level[1].cat);
634 ebitmap_destroy(&usrdatum->dfltlevel.cat);
635 }
622 kfree(datum); 636 kfree(datum);
623 return 0; 637 return 0;
624} 638}
@@ -628,9 +642,11 @@ static int sens_destroy(void *key, void *datum, void *p)
628 struct level_datum *levdatum; 642 struct level_datum *levdatum;
629 643
630 kfree(key); 644 kfree(key);
631 levdatum = datum; 645 if (datum) {
632 ebitmap_destroy(&levdatum->level->cat); 646 levdatum = datum;
633 kfree(levdatum->level); 647 ebitmap_destroy(&levdatum->level->cat);
648 kfree(levdatum->level);
649 }
634 kfree(datum); 650 kfree(datum);
635 return 0; 651 return 0;
636} 652}
@@ -695,13 +711,16 @@ void policydb_destroy(struct policydb *p)
695 hashtab_destroy(p->symtab[i].table); 711 hashtab_destroy(p->symtab[i].table);
696 } 712 }
697 713
698 for (i = 0; i < SYM_NUM; i++) 714 for (i = 0; i < SYM_NUM; i++) {
699 kfree(p->sym_val_to_name[i]); 715 if (p->sym_val_to_name[i])
716 flex_array_free(p->sym_val_to_name[i]);
717 }
700 718
701 kfree(p->class_val_to_struct); 719 kfree(p->class_val_to_struct);
702 kfree(p->role_val_to_struct); 720 kfree(p->role_val_to_struct);
703 kfree(p->user_val_to_struct); 721 kfree(p->user_val_to_struct);
704 kfree(p->type_val_to_struct); 722 if (p->type_val_to_struct_array)
723 flex_array_free(p->type_val_to_struct_array);
705 724
706 avtab_destroy(&p->te_avtab); 725 avtab_destroy(&p->te_avtab);
707 726
@@ -785,19 +804,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
785 804
786 head = p->ocontexts[OCON_ISID]; 805 head = p->ocontexts[OCON_ISID];
787 for (c = head; c; c = c->next) { 806 for (c = head; c; c = c->next) {
807 rc = -EINVAL;
788 if (!c->context[0].user) { 808 if (!c->context[0].user) {
789 printk(KERN_ERR "SELinux: SID %s was never " 809 printk(KERN_ERR "SELinux: SID %s was never defined.\n",
790 "defined.\n", c->u.name); 810 c->u.name);
791 rc = -EINVAL;
792 goto out; 811 goto out;
793 } 812 }
794 if (sidtab_insert(s, c->sid[0], &c->context[0])) { 813
795 printk(KERN_ERR "SELinux: unable to load initial " 814 rc = sidtab_insert(s, c->sid[0], &c->context[0]);
796 "SID %s.\n", c->u.name); 815 if (rc) {
797 rc = -EINVAL; 816 printk(KERN_ERR "SELinux: unable to load initial SID %s.\n",
817 c->u.name);
798 goto out; 818 goto out;
799 } 819 }
800 } 820 }
821 rc = 0;
801out: 822out:
802 return rc; 823 return rc;
803} 824}
@@ -846,8 +867,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
846 * Role must be authorized for the type. 867 * Role must be authorized for the type.
847 */ 868 */
848 role = p->role_val_to_struct[c->role - 1]; 869 role = p->role_val_to_struct[c->role - 1];
849 if (!ebitmap_get_bit(&role->types, 870 if (!ebitmap_get_bit(&role->types, c->type - 1))
850 c->type - 1))
851 /* role may not be associated with type */ 871 /* role may not be associated with type */
852 return 0; 872 return 0;
853 873
@@ -858,8 +878,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
858 if (!usrdatum) 878 if (!usrdatum)
859 return 0; 879 return 0;
860 880
861 if (!ebitmap_get_bit(&usrdatum->roles, 881 if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1))
862 c->role - 1))
863 /* user may not be associated with role */ 882 /* user may not be associated with role */
864 return 0; 883 return 0;
865 } 884 }
@@ -881,20 +900,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
881 int rc; 900 int rc;
882 901
883 rc = next_entry(buf, fp, sizeof(u32)); 902 rc = next_entry(buf, fp, sizeof(u32));
884 if (rc < 0) 903 if (rc)
885 goto out; 904 goto out;
886 905
906 rc = -EINVAL;
887 items = le32_to_cpu(buf[0]); 907 items = le32_to_cpu(buf[0]);
888 if (items > ARRAY_SIZE(buf)) { 908 if (items > ARRAY_SIZE(buf)) {
889 printk(KERN_ERR "SELinux: mls: range overflow\n"); 909 printk(KERN_ERR "SELinux: mls: range overflow\n");
890 rc = -EINVAL;
891 goto out; 910 goto out;
892 } 911 }
912
893 rc = next_entry(buf, fp, sizeof(u32) * items); 913 rc = next_entry(buf, fp, sizeof(u32) * items);
894 if (rc < 0) { 914 if (rc) {
895 printk(KERN_ERR "SELinux: mls: truncated range\n"); 915 printk(KERN_ERR "SELinux: mls: truncated range\n");
896 goto out; 916 goto out;
897 } 917 }
918
898 r->level[0].sens = le32_to_cpu(buf[0]); 919 r->level[0].sens = le32_to_cpu(buf[0]);
899 if (items > 1) 920 if (items > 1)
900 r->level[1].sens = le32_to_cpu(buf[1]); 921 r->level[1].sens = le32_to_cpu(buf[1]);
@@ -903,15 +924,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
903 924
904 rc = ebitmap_read(&r->level[0].cat, fp); 925 rc = ebitmap_read(&r->level[0].cat, fp);
905 if (rc) { 926 if (rc) {
906 printk(KERN_ERR "SELinux: mls: error reading low " 927 printk(KERN_ERR "SELinux: mls: error reading low categories\n");
907 "categories\n");
908 goto out; 928 goto out;
909 } 929 }
910 if (items > 1) { 930 if (items > 1) {
911 rc = ebitmap_read(&r->level[1].cat, fp); 931 rc = ebitmap_read(&r->level[1].cat, fp);
912 if (rc) { 932 if (rc) {
913 printk(KERN_ERR "SELinux: mls: error reading high " 933 printk(KERN_ERR "SELinux: mls: error reading high categories\n");
914 "categories\n");
915 goto bad_high; 934 goto bad_high;
916 } 935 }
917 } else { 936 } else {
@@ -922,12 +941,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
922 } 941 }
923 } 942 }
924 943
925 rc = 0; 944 return 0;
926out:
927 return rc;
928bad_high: 945bad_high:
929 ebitmap_destroy(&r->level[0].cat); 946 ebitmap_destroy(&r->level[0].cat);
930 goto out; 947out:
948 return rc;
931} 949}
932 950
933/* 951/*
@@ -942,7 +960,7 @@ static int context_read_and_validate(struct context *c,
942 int rc; 960 int rc;
943 961
944 rc = next_entry(buf, fp, sizeof buf); 962 rc = next_entry(buf, fp, sizeof buf);
945 if (rc < 0) { 963 if (rc) {
946 printk(KERN_ERR "SELinux: context truncated\n"); 964 printk(KERN_ERR "SELinux: context truncated\n");
947 goto out; 965 goto out;
948 } 966 }
@@ -950,19 +968,20 @@ static int context_read_and_validate(struct context *c,
950 c->role = le32_to_cpu(buf[1]); 968 c->role = le32_to_cpu(buf[1]);
951 c->type = le32_to_cpu(buf[2]); 969 c->type = le32_to_cpu(buf[2]);
952 if (p->policyvers >= POLICYDB_VERSION_MLS) { 970 if (p->policyvers >= POLICYDB_VERSION_MLS) {
953 if (mls_read_range_helper(&c->range, fp)) { 971 rc = mls_read_range_helper(&c->range, fp);
954 printk(KERN_ERR "SELinux: error reading MLS range of " 972 if (rc) {
955 "context\n"); 973 printk(KERN_ERR "SELinux: error reading MLS range of context\n");
956 rc = -EINVAL;
957 goto out; 974 goto out;
958 } 975 }
959 } 976 }
960 977
978 rc = -EINVAL;
961 if (!policydb_context_isvalid(p, c)) { 979 if (!policydb_context_isvalid(p, c)) {
962 printk(KERN_ERR "SELinux: invalid security context\n"); 980 printk(KERN_ERR "SELinux: invalid security context\n");
963 context_destroy(c); 981 context_destroy(c);
964 rc = -EINVAL; 982 goto out;
965 } 983 }
984 rc = 0;
966out: 985out:
967 return rc; 986 return rc;
968} 987}
@@ -981,37 +1000,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
981 __le32 buf[2]; 1000 __le32 buf[2];
982 u32 len; 1001 u32 len;
983 1002
1003 rc = -ENOMEM;
984 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); 1004 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
985 if (!perdatum) { 1005 if (!perdatum)
986 rc = -ENOMEM; 1006 goto bad;
987 goto out;
988 }
989 1007
990 rc = next_entry(buf, fp, sizeof buf); 1008 rc = next_entry(buf, fp, sizeof buf);
991 if (rc < 0) 1009 if (rc)
992 goto bad; 1010 goto bad;
993 1011
994 len = le32_to_cpu(buf[0]); 1012 len = le32_to_cpu(buf[0]);
995 perdatum->value = le32_to_cpu(buf[1]); 1013 perdatum->value = le32_to_cpu(buf[1]);
996 1014
1015 rc = -ENOMEM;
997 key = kmalloc(len + 1, GFP_KERNEL); 1016 key = kmalloc(len + 1, GFP_KERNEL);
998 if (!key) { 1017 if (!key)
999 rc = -ENOMEM;
1000 goto bad; 1018 goto bad;
1001 } 1019
1002 rc = next_entry(key, fp, len); 1020 rc = next_entry(key, fp, len);
1003 if (rc < 0) 1021 if (rc)
1004 goto bad; 1022 goto bad;
1005 key[len] = '\0'; 1023 key[len] = '\0';
1006 1024
1007 rc = hashtab_insert(h, key, perdatum); 1025 rc = hashtab_insert(h, key, perdatum);
1008 if (rc) 1026 if (rc)
1009 goto bad; 1027 goto bad;
1010out: 1028
1011 return rc; 1029 return 0;
1012bad: 1030bad:
1013 perm_destroy(key, perdatum, NULL); 1031 perm_destroy(key, perdatum, NULL);
1014 goto out; 1032 return rc;
1015} 1033}
1016 1034
1017static int common_read(struct policydb *p, struct hashtab *h, void *fp) 1035static int common_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1022,14 +1040,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1022 u32 len, nel; 1040 u32 len, nel;
1023 int i, rc; 1041 int i, rc;
1024 1042
1043 rc = -ENOMEM;
1025 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); 1044 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
1026 if (!comdatum) { 1045 if (!comdatum)
1027 rc = -ENOMEM; 1046 goto bad;
1028 goto out;
1029 }
1030 1047
1031 rc = next_entry(buf, fp, sizeof buf); 1048 rc = next_entry(buf, fp, sizeof buf);
1032 if (rc < 0) 1049 if (rc)
1033 goto bad; 1050 goto bad;
1034 1051
1035 len = le32_to_cpu(buf[0]); 1052 len = le32_to_cpu(buf[0]);
@@ -1041,13 +1058,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1041 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1058 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1042 nel = le32_to_cpu(buf[3]); 1059 nel = le32_to_cpu(buf[3]);
1043 1060
1061 rc = -ENOMEM;
1044 key = kmalloc(len + 1, GFP_KERNEL); 1062 key = kmalloc(len + 1, GFP_KERNEL);
1045 if (!key) { 1063 if (!key)
1046 rc = -ENOMEM;
1047 goto bad; 1064 goto bad;
1048 } 1065
1049 rc = next_entry(key, fp, len); 1066 rc = next_entry(key, fp, len);
1050 if (rc < 0) 1067 if (rc)
1051 goto bad; 1068 goto bad;
1052 key[len] = '\0'; 1069 key[len] = '\0';
1053 1070
@@ -1060,11 +1077,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1060 rc = hashtab_insert(h, key, comdatum); 1077 rc = hashtab_insert(h, key, comdatum);
1061 if (rc) 1078 if (rc)
1062 goto bad; 1079 goto bad;
1063out: 1080 return 0;
1064 return rc;
1065bad: 1081bad:
1066 common_destroy(key, comdatum, NULL); 1082 common_destroy(key, comdatum, NULL);
1067 goto out; 1083 return rc;
1068} 1084}
1069 1085
1070static int read_cons_helper(struct constraint_node **nodep, int ncons, 1086static int read_cons_helper(struct constraint_node **nodep, int ncons,
@@ -1088,7 +1104,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1088 *nodep = c; 1104 *nodep = c;
1089 1105
1090 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 1106 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1091 if (rc < 0) 1107 if (rc)
1092 return rc; 1108 return rc;
1093 c->permissions = le32_to_cpu(buf[0]); 1109 c->permissions = le32_to_cpu(buf[0]);
1094 nexpr = le32_to_cpu(buf[1]); 1110 nexpr = le32_to_cpu(buf[1]);
@@ -1105,7 +1121,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1105 c->expr = e; 1121 c->expr = e;
1106 1122
1107 rc = next_entry(buf, fp, (sizeof(u32) * 3)); 1123 rc = next_entry(buf, fp, (sizeof(u32) * 3));
1108 if (rc < 0) 1124 if (rc)
1109 return rc; 1125 return rc;
1110 e->expr_type = le32_to_cpu(buf[0]); 1126 e->expr_type = le32_to_cpu(buf[0]);
1111 e->attr = le32_to_cpu(buf[1]); 1127 e->attr = le32_to_cpu(buf[1]);
@@ -1133,8 +1149,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1133 if (depth == (CEXPR_MAXDEPTH - 1)) 1149 if (depth == (CEXPR_MAXDEPTH - 1))
1134 return -EINVAL; 1150 return -EINVAL;
1135 depth++; 1151 depth++;
1136 if (ebitmap_read(&e->names, fp)) 1152 rc = ebitmap_read(&e->names, fp);
1137 return -EINVAL; 1153 if (rc)
1154 return rc;
1138 break; 1155 break;
1139 default: 1156 default:
1140 return -EINVAL; 1157 return -EINVAL;
@@ -1157,14 +1174,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1157 u32 len, len2, ncons, nel; 1174 u32 len, len2, ncons, nel;
1158 int i, rc; 1175 int i, rc;
1159 1176
1177 rc = -ENOMEM;
1160 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); 1178 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
1161 if (!cladatum) { 1179 if (!cladatum)
1162 rc = -ENOMEM; 1180 goto bad;
1163 goto out;
1164 }
1165 1181
1166 rc = next_entry(buf, fp, sizeof(u32)*6); 1182 rc = next_entry(buf, fp, sizeof(u32)*6);
1167 if (rc < 0) 1183 if (rc)
1168 goto bad; 1184 goto bad;
1169 1185
1170 len = le32_to_cpu(buf[0]); 1186 len = le32_to_cpu(buf[0]);
@@ -1179,33 +1195,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1179 1195
1180 ncons = le32_to_cpu(buf[5]); 1196 ncons = le32_to_cpu(buf[5]);
1181 1197
1198 rc = -ENOMEM;
1182 key = kmalloc(len + 1, GFP_KERNEL); 1199 key = kmalloc(len + 1, GFP_KERNEL);
1183 if (!key) { 1200 if (!key)
1184 rc = -ENOMEM;
1185 goto bad; 1201 goto bad;
1186 } 1202
1187 rc = next_entry(key, fp, len); 1203 rc = next_entry(key, fp, len);
1188 if (rc < 0) 1204 if (rc)
1189 goto bad; 1205 goto bad;
1190 key[len] = '\0'; 1206 key[len] = '\0';
1191 1207
1192 if (len2) { 1208 if (len2) {
1209 rc = -ENOMEM;
1193 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); 1210 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
1194 if (!cladatum->comkey) { 1211 if (!cladatum->comkey)
1195 rc = -ENOMEM;
1196 goto bad; 1212 goto bad;
1197 }
1198 rc = next_entry(cladatum->comkey, fp, len2); 1213 rc = next_entry(cladatum->comkey, fp, len2);
1199 if (rc < 0) 1214 if (rc)
1200 goto bad; 1215 goto bad;
1201 cladatum->comkey[len2] = '\0'; 1216 cladatum->comkey[len2] = '\0';
1202 1217
1203 cladatum->comdatum = hashtab_search(p->p_commons.table, 1218 rc = -EINVAL;
1204 cladatum->comkey); 1219 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
1205 if (!cladatum->comdatum) { 1220 if (!cladatum->comdatum) {
1206 printk(KERN_ERR "SELinux: unknown common %s\n", 1221 printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey);
1207 cladatum->comkey);
1208 rc = -EINVAL;
1209 goto bad; 1222 goto bad;
1210 } 1223 }
1211 } 1224 }
@@ -1222,7 +1235,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1222 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { 1235 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {
1223 /* grab the validatetrans rules */ 1236 /* grab the validatetrans rules */
1224 rc = next_entry(buf, fp, sizeof(u32)); 1237 rc = next_entry(buf, fp, sizeof(u32));
1225 if (rc < 0) 1238 if (rc)
1226 goto bad; 1239 goto bad;
1227 ncons = le32_to_cpu(buf[0]); 1240 ncons = le32_to_cpu(buf[0]);
1228 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); 1241 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
@@ -1234,12 +1247,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1234 if (rc) 1247 if (rc)
1235 goto bad; 1248 goto bad;
1236 1249
1237 rc = 0; 1250 return 0;
1238out:
1239 return rc;
1240bad: 1251bad:
1241 cls_destroy(key, cladatum, NULL); 1252 cls_destroy(key, cladatum, NULL);
1242 goto out; 1253 return rc;
1243} 1254}
1244 1255
1245static int role_read(struct policydb *p, struct hashtab *h, void *fp) 1256static int role_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1250,17 +1261,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1250 __le32 buf[3]; 1261 __le32 buf[3];
1251 u32 len; 1262 u32 len;
1252 1263
1264 rc = -ENOMEM;
1253 role = kzalloc(sizeof(*role), GFP_KERNEL); 1265 role = kzalloc(sizeof(*role), GFP_KERNEL);
1254 if (!role) { 1266 if (!role)
1255 rc = -ENOMEM; 1267 goto bad;
1256 goto out;
1257 }
1258 1268
1259 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1269 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1260 to_read = 3; 1270 to_read = 3;
1261 1271
1262 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1272 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1263 if (rc < 0) 1273 if (rc)
1264 goto bad; 1274 goto bad;
1265 1275
1266 len = le32_to_cpu(buf[0]); 1276 len = le32_to_cpu(buf[0]);
@@ -1268,13 +1278,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1268 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1278 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1269 role->bounds = le32_to_cpu(buf[2]); 1279 role->bounds = le32_to_cpu(buf[2]);
1270 1280
1281 rc = -ENOMEM;
1271 key = kmalloc(len + 1, GFP_KERNEL); 1282 key = kmalloc(len + 1, GFP_KERNEL);
1272 if (!key) { 1283 if (!key)
1273 rc = -ENOMEM;
1274 goto bad; 1284 goto bad;
1275 } 1285
1276 rc = next_entry(key, fp, len); 1286 rc = next_entry(key, fp, len);
1277 if (rc < 0) 1287 if (rc)
1278 goto bad; 1288 goto bad;
1279 key[len] = '\0'; 1289 key[len] = '\0';
1280 1290
@@ -1287,10 +1297,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1287 goto bad; 1297 goto bad;
1288 1298
1289 if (strcmp(key, OBJECT_R) == 0) { 1299 if (strcmp(key, OBJECT_R) == 0) {
1300 rc = -EINVAL;
1290 if (role->value != OBJECT_R_VAL) { 1301 if (role->value != OBJECT_R_VAL) {
1291 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", 1302 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n",
1292 OBJECT_R, role->value); 1303 OBJECT_R, role->value);
1293 rc = -EINVAL;
1294 goto bad; 1304 goto bad;
1295 } 1305 }
1296 rc = 0; 1306 rc = 0;
@@ -1300,11 +1310,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1300 rc = hashtab_insert(h, key, role); 1310 rc = hashtab_insert(h, key, role);
1301 if (rc) 1311 if (rc)
1302 goto bad; 1312 goto bad;
1303out: 1313 return 0;
1304 return rc;
1305bad: 1314bad:
1306 role_destroy(key, role, NULL); 1315 role_destroy(key, role, NULL);
1307 goto out; 1316 return rc;
1308} 1317}
1309 1318
1310static int type_read(struct policydb *p, struct hashtab *h, void *fp) 1319static int type_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1315,17 +1324,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1315 __le32 buf[4]; 1324 __le32 buf[4];
1316 u32 len; 1325 u32 len;
1317 1326
1327 rc = -ENOMEM;
1318 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); 1328 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL);
1319 if (!typdatum) { 1329 if (!typdatum)
1320 rc = -ENOMEM; 1330 goto bad;
1321 return rc;
1322 }
1323 1331
1324 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1332 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1325 to_read = 4; 1333 to_read = 4;
1326 1334
1327 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1335 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1328 if (rc < 0) 1336 if (rc)
1329 goto bad; 1337 goto bad;
1330 1338
1331 len = le32_to_cpu(buf[0]); 1339 len = le32_to_cpu(buf[0]);
@@ -1343,24 +1351,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1343 typdatum->primary = le32_to_cpu(buf[2]); 1351 typdatum->primary = le32_to_cpu(buf[2]);
1344 } 1352 }
1345 1353
1354 rc = -ENOMEM;
1346 key = kmalloc(len + 1, GFP_KERNEL); 1355 key = kmalloc(len + 1, GFP_KERNEL);
1347 if (!key) { 1356 if (!key)
1348 rc = -ENOMEM;
1349 goto bad; 1357 goto bad;
1350 }
1351 rc = next_entry(key, fp, len); 1358 rc = next_entry(key, fp, len);
1352 if (rc < 0) 1359 if (rc)
1353 goto bad; 1360 goto bad;
1354 key[len] = '\0'; 1361 key[len] = '\0';
1355 1362
1356 rc = hashtab_insert(h, key, typdatum); 1363 rc = hashtab_insert(h, key, typdatum);
1357 if (rc) 1364 if (rc)
1358 goto bad; 1365 goto bad;
1359out: 1366 return 0;
1360 return rc;
1361bad: 1367bad:
1362 type_destroy(key, typdatum, NULL); 1368 type_destroy(key, typdatum, NULL);
1363 goto out; 1369 return rc;
1364} 1370}
1365 1371
1366 1372
@@ -1376,22 +1382,18 @@ static int mls_read_level(struct mls_level *lp, void *fp)
1376 memset(lp, 0, sizeof(*lp)); 1382 memset(lp, 0, sizeof(*lp));
1377 1383
1378 rc = next_entry(buf, fp, sizeof buf); 1384 rc = next_entry(buf, fp, sizeof buf);
1379 if (rc < 0) { 1385 if (rc) {
1380 printk(KERN_ERR "SELinux: mls: truncated level\n"); 1386 printk(KERN_ERR "SELinux: mls: truncated level\n");
1381 goto bad; 1387 return rc;
1382 } 1388 }
1383 lp->sens = le32_to_cpu(buf[0]); 1389 lp->sens = le32_to_cpu(buf[0]);
1384 1390
1385 if (ebitmap_read(&lp->cat, fp)) { 1391 rc = ebitmap_read(&lp->cat, fp);
1386 printk(KERN_ERR "SELinux: mls: error reading level " 1392 if (rc) {
1387 "categories\n"); 1393 printk(KERN_ERR "SELinux: mls: error reading level categories\n");
1388 goto bad; 1394 return rc;
1389 } 1395 }
1390
1391 return 0; 1396 return 0;
1392
1393bad:
1394 return -EINVAL;
1395} 1397}
1396 1398
1397static int user_read(struct policydb *p, struct hashtab *h, void *fp) 1399static int user_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1402,17 +1404,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1402 __le32 buf[3]; 1404 __le32 buf[3];
1403 u32 len; 1405 u32 len;
1404 1406
1407 rc = -ENOMEM;
1405 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); 1408 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
1406 if (!usrdatum) { 1409 if (!usrdatum)
1407 rc = -ENOMEM; 1410 goto bad;
1408 goto out;
1409 }
1410 1411
1411 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1412 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1412 to_read = 3; 1413 to_read = 3;
1413 1414
1414 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1415 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1415 if (rc < 0) 1416 if (rc)
1416 goto bad; 1417 goto bad;
1417 1418
1418 len = le32_to_cpu(buf[0]); 1419 len = le32_to_cpu(buf[0]);
@@ -1420,13 +1421,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1420 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1421 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1421 usrdatum->bounds = le32_to_cpu(buf[2]); 1422 usrdatum->bounds = le32_to_cpu(buf[2]);
1422 1423
1424 rc = -ENOMEM;
1423 key = kmalloc(len + 1, GFP_KERNEL); 1425 key = kmalloc(len + 1, GFP_KERNEL);
1424 if (!key) { 1426 if (!key)
1425 rc = -ENOMEM;
1426 goto bad; 1427 goto bad;
1427 }
1428 rc = next_entry(key, fp, len); 1428 rc = next_entry(key, fp, len);
1429 if (rc < 0) 1429 if (rc)
1430 goto bad; 1430 goto bad;
1431 key[len] = '\0'; 1431 key[len] = '\0';
1432 1432
@@ -1446,11 +1446,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1446 rc = hashtab_insert(h, key, usrdatum); 1446 rc = hashtab_insert(h, key, usrdatum);
1447 if (rc) 1447 if (rc)
1448 goto bad; 1448 goto bad;
1449out: 1449 return 0;
1450 return rc;
1451bad: 1450bad:
1452 user_destroy(key, usrdatum, NULL); 1451 user_destroy(key, usrdatum, NULL);
1453 goto out; 1452 return rc;
1454} 1453}
1455 1454
1456static int sens_read(struct policydb *p, struct hashtab *h, void *fp) 1455static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1461,47 +1460,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1461 __le32 buf[2]; 1460 __le32 buf[2];
1462 u32 len; 1461 u32 len;
1463 1462
1463 rc = -ENOMEM;
1464 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); 1464 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
1465 if (!levdatum) { 1465 if (!levdatum)
1466 rc = -ENOMEM; 1466 goto bad;
1467 goto out;
1468 }
1469 1467
1470 rc = next_entry(buf, fp, sizeof buf); 1468 rc = next_entry(buf, fp, sizeof buf);
1471 if (rc < 0) 1469 if (rc)
1472 goto bad; 1470 goto bad;
1473 1471
1474 len = le32_to_cpu(buf[0]); 1472 len = le32_to_cpu(buf[0]);
1475 levdatum->isalias = le32_to_cpu(buf[1]); 1473 levdatum->isalias = le32_to_cpu(buf[1]);
1476 1474
1475 rc = -ENOMEM;
1477 key = kmalloc(len + 1, GFP_ATOMIC); 1476 key = kmalloc(len + 1, GFP_ATOMIC);
1478 if (!key) { 1477 if (!key)
1479 rc = -ENOMEM;
1480 goto bad; 1478 goto bad;
1481 }
1482 rc = next_entry(key, fp, len); 1479 rc = next_entry(key, fp, len);
1483 if (rc < 0) 1480 if (rc)
1484 goto bad; 1481 goto bad;
1485 key[len] = '\0'; 1482 key[len] = '\0';
1486 1483
1484 rc = -ENOMEM;
1487 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1485 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
1488 if (!levdatum->level) { 1486 if (!levdatum->level)
1489 rc = -ENOMEM;
1490 goto bad; 1487 goto bad;
1491 } 1488
1492 if (mls_read_level(levdatum->level, fp)) { 1489 rc = mls_read_level(levdatum->level, fp);
1493 rc = -EINVAL; 1490 if (rc)
1494 goto bad; 1491 goto bad;
1495 }
1496 1492
1497 rc = hashtab_insert(h, key, levdatum); 1493 rc = hashtab_insert(h, key, levdatum);
1498 if (rc) 1494 if (rc)
1499 goto bad; 1495 goto bad;
1500out: 1496 return 0;
1501 return rc;
1502bad: 1497bad:
1503 sens_destroy(key, levdatum, NULL); 1498 sens_destroy(key, levdatum, NULL);
1504 goto out; 1499 return rc;
1505} 1500}
1506 1501
1507static int cat_read(struct policydb *p, struct hashtab *h, void *fp) 1502static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1512,39 +1507,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1512 __le32 buf[3]; 1507 __le32 buf[3];
1513 u32 len; 1508 u32 len;
1514 1509
1510 rc = -ENOMEM;
1515 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); 1511 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
1516 if (!catdatum) { 1512 if (!catdatum)
1517 rc = -ENOMEM; 1513 goto bad;
1518 goto out;
1519 }
1520 1514
1521 rc = next_entry(buf, fp, sizeof buf); 1515 rc = next_entry(buf, fp, sizeof buf);
1522 if (rc < 0) 1516 if (rc)
1523 goto bad; 1517 goto bad;
1524 1518
1525 len = le32_to_cpu(buf[0]); 1519 len = le32_to_cpu(buf[0]);
1526 catdatum->value = le32_to_cpu(buf[1]); 1520 catdatum->value = le32_to_cpu(buf[1]);
1527 catdatum->isalias = le32_to_cpu(buf[2]); 1521 catdatum->isalias = le32_to_cpu(buf[2]);
1528 1522
1523 rc = -ENOMEM;
1529 key = kmalloc(len + 1, GFP_ATOMIC); 1524 key = kmalloc(len + 1, GFP_ATOMIC);
1530 if (!key) { 1525 if (!key)
1531 rc = -ENOMEM;
1532 goto bad; 1526 goto bad;
1533 }
1534 rc = next_entry(key, fp, len); 1527 rc = next_entry(key, fp, len);
1535 if (rc < 0) 1528 if (rc)
1536 goto bad; 1529 goto bad;
1537 key[len] = '\0'; 1530 key[len] = '\0';
1538 1531
1539 rc = hashtab_insert(h, key, catdatum); 1532 rc = hashtab_insert(h, key, catdatum);
1540 if (rc) 1533 if (rc)
1541 goto bad; 1534 goto bad;
1542out: 1535 return 0;
1543 return rc;
1544
1545bad: 1536bad:
1546 cat_destroy(key, catdatum, NULL); 1537 cat_destroy(key, catdatum, NULL);
1547 goto out; 1538 return rc;
1548} 1539}
1549 1540
1550static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = 1541static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
@@ -1585,9 +1576,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap)
1585 printk(KERN_ERR 1576 printk(KERN_ERR
1586 "SELinux: boundary violated policy: " 1577 "SELinux: boundary violated policy: "
1587 "user=%s role=%s bounds=%s\n", 1578 "user=%s role=%s bounds=%s\n",
1588 p->p_user_val_to_name[user->value - 1], 1579 sym_name(p, SYM_USERS, user->value - 1),
1589 p->p_role_val_to_name[bit], 1580 sym_name(p, SYM_ROLES, bit),
1590 p->p_user_val_to_name[upper->value - 1]); 1581 sym_name(p, SYM_USERS, upper->value - 1));
1591 1582
1592 return -EINVAL; 1583 return -EINVAL;
1593 } 1584 }
@@ -1622,9 +1613,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1622 printk(KERN_ERR 1613 printk(KERN_ERR
1623 "SELinux: boundary violated policy: " 1614 "SELinux: boundary violated policy: "
1624 "role=%s type=%s bounds=%s\n", 1615 "role=%s type=%s bounds=%s\n",
1625 p->p_role_val_to_name[role->value - 1], 1616 sym_name(p, SYM_ROLES, role->value - 1),
1626 p->p_type_val_to_name[bit], 1617 sym_name(p, SYM_TYPES, bit),
1627 p->p_role_val_to_name[upper->value - 1]); 1618 sym_name(p, SYM_ROLES, upper->value - 1));
1628 1619
1629 return -EINVAL; 1620 return -EINVAL;
1630 } 1621 }
@@ -1648,12 +1639,15 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1648 return -EINVAL; 1639 return -EINVAL;
1649 } 1640 }
1650 1641
1651 upper = p->type_val_to_struct[upper->bounds - 1]; 1642 upper = flex_array_get_ptr(p->type_val_to_struct_array,
1643 upper->bounds - 1);
1644 BUG_ON(!upper);
1645
1652 if (upper->attribute) { 1646 if (upper->attribute) {
1653 printk(KERN_ERR "SELinux: type %s: " 1647 printk(KERN_ERR "SELinux: type %s: "
1654 "bounded by attribute %s", 1648 "bounded by attribute %s",
1655 (char *) key, 1649 (char *) key,
1656 p->p_type_val_to_name[upper->value - 1]); 1650 sym_name(p, SYM_TYPES, upper->value - 1));
1657 return -EINVAL; 1651 return -EINVAL;
1658 } 1652 }
1659 } 1653 }
@@ -2066,13 +2060,14 @@ int policydb_read(struct policydb *p, void *fp)
2066 2060
2067 rc = policydb_init(p); 2061 rc = policydb_init(p);
2068 if (rc) 2062 if (rc)
2069 goto out; 2063 return rc;
2070 2064
2071 /* Read the magic number and string length. */ 2065 /* Read the magic number and string length. */
2072 rc = next_entry(buf, fp, sizeof(u32) * 2); 2066 rc = next_entry(buf, fp, sizeof(u32) * 2);
2073 if (rc < 0) 2067 if (rc)
2074 goto bad; 2068 goto bad;
2075 2069
2070 rc = -EINVAL;
2076 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { 2071 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
2077 printk(KERN_ERR "SELinux: policydb magic number 0x%x does " 2072 printk(KERN_ERR "SELinux: policydb magic number 0x%x does "
2078 "not match expected magic number 0x%x\n", 2073 "not match expected magic number 0x%x\n",
@@ -2080,6 +2075,7 @@ int policydb_read(struct policydb *p, void *fp)
2080 goto bad; 2075 goto bad;
2081 } 2076 }
2082 2077
2078 rc = -EINVAL;
2083 len = le32_to_cpu(buf[1]); 2079 len = le32_to_cpu(buf[1]);
2084 if (len != strlen(POLICYDB_STRING)) { 2080 if (len != strlen(POLICYDB_STRING)) {
2085 printk(KERN_ERR "SELinux: policydb string length %d does not " 2081 printk(KERN_ERR "SELinux: policydb string length %d does not "
@@ -2087,19 +2083,23 @@ int policydb_read(struct policydb *p, void *fp)
2087 len, strlen(POLICYDB_STRING)); 2083 len, strlen(POLICYDB_STRING));
2088 goto bad; 2084 goto bad;
2089 } 2085 }
2086
2087 rc = -ENOMEM;
2090 policydb_str = kmalloc(len + 1, GFP_KERNEL); 2088 policydb_str = kmalloc(len + 1, GFP_KERNEL);
2091 if (!policydb_str) { 2089 if (!policydb_str) {
2092 printk(KERN_ERR "SELinux: unable to allocate memory for policydb " 2090 printk(KERN_ERR "SELinux: unable to allocate memory for policydb "
2093 "string of length %d\n", len); 2091 "string of length %d\n", len);
2094 rc = -ENOMEM;
2095 goto bad; 2092 goto bad;
2096 } 2093 }
2094
2097 rc = next_entry(policydb_str, fp, len); 2095 rc = next_entry(policydb_str, fp, len);
2098 if (rc < 0) { 2096 if (rc) {
2099 printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); 2097 printk(KERN_ERR "SELinux: truncated policydb string identifier\n");
2100 kfree(policydb_str); 2098 kfree(policydb_str);
2101 goto bad; 2099 goto bad;
2102 } 2100 }
2101
2102 rc = -EINVAL;
2103 policydb_str[len] = '\0'; 2103 policydb_str[len] = '\0';
2104 if (strcmp(policydb_str, POLICYDB_STRING)) { 2104 if (strcmp(policydb_str, POLICYDB_STRING)) {
2105 printk(KERN_ERR "SELinux: policydb string %s does not match " 2105 printk(KERN_ERR "SELinux: policydb string %s does not match "
@@ -2113,9 +2113,10 @@ int policydb_read(struct policydb *p, void *fp)
2113 2113
2114 /* Read the version and table sizes. */ 2114 /* Read the version and table sizes. */
2115 rc = next_entry(buf, fp, sizeof(u32)*4); 2115 rc = next_entry(buf, fp, sizeof(u32)*4);
2116 if (rc < 0) 2116 if (rc)
2117 goto bad; 2117 goto bad;
2118 2118
2119 rc = -EINVAL;
2119 p->policyvers = le32_to_cpu(buf[0]); 2120 p->policyvers = le32_to_cpu(buf[0]);
2120 if (p->policyvers < POLICYDB_VERSION_MIN || 2121 if (p->policyvers < POLICYDB_VERSION_MIN ||
2121 p->policyvers > POLICYDB_VERSION_MAX) { 2122 p->policyvers > POLICYDB_VERSION_MAX) {
@@ -2128,6 +2129,7 @@ int policydb_read(struct policydb *p, void *fp)
2128 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 2129 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
2129 p->mls_enabled = 1; 2130 p->mls_enabled = 1;
2130 2131
2132 rc = -EINVAL;
2131 if (p->policyvers < POLICYDB_VERSION_MLS) { 2133 if (p->policyvers < POLICYDB_VERSION_MLS) {
2132 printk(KERN_ERR "SELinux: security policydb version %d " 2134 printk(KERN_ERR "SELinux: security policydb version %d "
2133 "(MLS) not backwards compatible\n", 2135 "(MLS) not backwards compatible\n",
@@ -2138,14 +2140,19 @@ int policydb_read(struct policydb *p, void *fp)
2138 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 2140 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
2139 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 2141 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
2140 2142
2141 if (p->policyvers >= POLICYDB_VERSION_POLCAP && 2143 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
2142 ebitmap_read(&p->policycaps, fp) != 0) 2144 rc = ebitmap_read(&p->policycaps, fp);
2143 goto bad; 2145 if (rc)
2146 goto bad;
2147 }
2144 2148
2145 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 2149 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
2146 ebitmap_read(&p->permissive_map, fp) != 0) 2150 rc = ebitmap_read(&p->permissive_map, fp);
2147 goto bad; 2151 if (rc)
2152 goto bad;
2153 }
2148 2154
2155 rc = -EINVAL;
2149 info = policydb_lookup_compat(p->policyvers); 2156 info = policydb_lookup_compat(p->policyvers);
2150 if (!info) { 2157 if (!info) {
2151 printk(KERN_ERR "SELinux: unable to find policy compat info " 2158 printk(KERN_ERR "SELinux: unable to find policy compat info "
@@ -2153,6 +2160,7 @@ int policydb_read(struct policydb *p, void *fp)
2153 goto bad; 2160 goto bad;
2154 } 2161 }
2155 2162
2163 rc = -EINVAL;
2156 if (le32_to_cpu(buf[2]) != info->sym_num || 2164 if (le32_to_cpu(buf[2]) != info->sym_num ||
2157 le32_to_cpu(buf[3]) != info->ocon_num) { 2165 le32_to_cpu(buf[3]) != info->ocon_num) {
2158 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " 2166 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do "
@@ -2164,7 +2172,7 @@ int policydb_read(struct policydb *p, void *fp)
2164 2172
2165 for (i = 0; i < info->sym_num; i++) { 2173 for (i = 0; i < info->sym_num; i++) {
2166 rc = next_entry(buf, fp, sizeof(u32)*2); 2174 rc = next_entry(buf, fp, sizeof(u32)*2);
2167 if (rc < 0) 2175 if (rc)
2168 goto bad; 2176 goto bad;
2169 nprim = le32_to_cpu(buf[0]); 2177 nprim = le32_to_cpu(buf[0]);
2170 nel = le32_to_cpu(buf[1]); 2178 nel = le32_to_cpu(buf[1]);
@@ -2188,78 +2196,73 @@ int policydb_read(struct policydb *p, void *fp)
2188 } 2196 }
2189 2197
2190 rc = next_entry(buf, fp, sizeof(u32)); 2198 rc = next_entry(buf, fp, sizeof(u32));
2191 if (rc < 0) 2199 if (rc)
2192 goto bad; 2200 goto bad;
2193 nel = le32_to_cpu(buf[0]); 2201 nel = le32_to_cpu(buf[0]);
2194 ltr = NULL; 2202 ltr = NULL;
2195 for (i = 0; i < nel; i++) { 2203 for (i = 0; i < nel; i++) {
2204 rc = -ENOMEM;
2196 tr = kzalloc(sizeof(*tr), GFP_KERNEL); 2205 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
2197 if (!tr) { 2206 if (!tr)
2198 rc = -ENOMEM;
2199 goto bad; 2207 goto bad;
2200 }
2201 if (ltr) 2208 if (ltr)
2202 ltr->next = tr; 2209 ltr->next = tr;
2203 else 2210 else
2204 p->role_tr = tr; 2211 p->role_tr = tr;
2205 rc = next_entry(buf, fp, sizeof(u32)*3); 2212 rc = next_entry(buf, fp, sizeof(u32)*3);
2206 if (rc < 0) 2213 if (rc)
2207 goto bad; 2214 goto bad;
2215
2216 rc = -EINVAL;
2208 tr->role = le32_to_cpu(buf[0]); 2217 tr->role = le32_to_cpu(buf[0]);
2209 tr->type = le32_to_cpu(buf[1]); 2218 tr->type = le32_to_cpu(buf[1]);
2210 tr->new_role = le32_to_cpu(buf[2]); 2219 tr->new_role = le32_to_cpu(buf[2]);
2211 if (!policydb_role_isvalid(p, tr->role) || 2220 if (!policydb_role_isvalid(p, tr->role) ||
2212 !policydb_type_isvalid(p, tr->type) || 2221 !policydb_type_isvalid(p, tr->type) ||
2213 !policydb_role_isvalid(p, tr->new_role)) { 2222 !policydb_role_isvalid(p, tr->new_role))
2214 rc = -EINVAL;
2215 goto bad; 2223 goto bad;
2216 }
2217 ltr = tr; 2224 ltr = tr;
2218 } 2225 }
2219 2226
2220 rc = next_entry(buf, fp, sizeof(u32)); 2227 rc = next_entry(buf, fp, sizeof(u32));
2221 if (rc < 0) 2228 if (rc)
2222 goto bad; 2229 goto bad;
2223 nel = le32_to_cpu(buf[0]); 2230 nel = le32_to_cpu(buf[0]);
2224 lra = NULL; 2231 lra = NULL;
2225 for (i = 0; i < nel; i++) { 2232 for (i = 0; i < nel; i++) {
2233 rc = -ENOMEM;
2226 ra = kzalloc(sizeof(*ra), GFP_KERNEL); 2234 ra = kzalloc(sizeof(*ra), GFP_KERNEL);
2227 if (!ra) { 2235 if (!ra)
2228 rc = -ENOMEM;
2229 goto bad; 2236 goto bad;
2230 }
2231 if (lra) 2237 if (lra)
2232 lra->next = ra; 2238 lra->next = ra;
2233 else 2239 else
2234 p->role_allow = ra; 2240 p->role_allow = ra;
2235 rc = next_entry(buf, fp, sizeof(u32)*2); 2241 rc = next_entry(buf, fp, sizeof(u32)*2);
2236 if (rc < 0) 2242 if (rc)
2237 goto bad; 2243 goto bad;
2244
2245 rc = -EINVAL;
2238 ra->role = le32_to_cpu(buf[0]); 2246 ra->role = le32_to_cpu(buf[0]);
2239 ra->new_role = le32_to_cpu(buf[1]); 2247 ra->new_role = le32_to_cpu(buf[1]);
2240 if (!policydb_role_isvalid(p, ra->role) || 2248 if (!policydb_role_isvalid(p, ra->role) ||
2241 !policydb_role_isvalid(p, ra->new_role)) { 2249 !policydb_role_isvalid(p, ra->new_role))
2242 rc = -EINVAL;
2243 goto bad; 2250 goto bad;
2244 }
2245 lra = ra; 2251 lra = ra;
2246 } 2252 }
2247 2253
2248 rc = policydb_index_classes(p); 2254 rc = policydb_index(p);
2249 if (rc)
2250 goto bad;
2251
2252 rc = policydb_index_others(p);
2253 if (rc) 2255 if (rc)
2254 goto bad; 2256 goto bad;
2255 2257
2258 rc = -EINVAL;
2256 p->process_class = string_to_security_class(p, "process"); 2259 p->process_class = string_to_security_class(p, "process");
2257 if (!p->process_class) 2260 if (!p->process_class)
2258 goto bad; 2261 goto bad;
2259 p->process_trans_perms = string_to_av_perm(p, p->process_class, 2262
2260 "transition"); 2263 rc = -EINVAL;
2261 p->process_trans_perms |= string_to_av_perm(p, p->process_class, 2264 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2262 "dyntransition"); 2265 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2263 if (!p->process_trans_perms) 2266 if (!p->process_trans_perms)
2264 goto bad; 2267 goto bad;
2265 2268
@@ -2312,8 +2315,6 @@ int policydb_read(struct policydb *p, void *fp)
2312out: 2315out:
2313 return rc; 2316 return rc;
2314bad: 2317bad:
2315 if (!rc)
2316 rc = -EINVAL;
2317 policydb_destroy(p); 2318 policydb_destroy(p);
2318 goto out; 2319 goto out;
2319} 2320}
@@ -3076,7 +3077,7 @@ int policydb_write(struct policydb *p, void *fp)
3076 if (!info) { 3077 if (!info) {
3077 printk(KERN_ERR "SELinux: compatibility lookup failed for policy " 3078 printk(KERN_ERR "SELinux: compatibility lookup failed for policy "
3078 "version %d", p->policyvers); 3079 "version %d", p->policyvers);
3079 return rc; 3080 return -EINVAL;
3080 } 3081 }
3081 3082
3082 buf[0] = cpu_to_le32(p->policyvers); 3083 buf[0] = cpu_to_le32(p->policyvers);
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 95d3d7de361e..4e3ab9d0b315 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -203,21 +203,13 @@ struct policydb {
203#define p_cats symtab[SYM_CATS] 203#define p_cats symtab[SYM_CATS]
204 204
205 /* symbol names indexed by (value - 1) */ 205 /* symbol names indexed by (value - 1) */
206 char **sym_val_to_name[SYM_NUM]; 206 struct flex_array *sym_val_to_name[SYM_NUM];
207#define p_common_val_to_name sym_val_to_name[SYM_COMMONS]
208#define p_class_val_to_name sym_val_to_name[SYM_CLASSES]
209#define p_role_val_to_name sym_val_to_name[SYM_ROLES]
210#define p_type_val_to_name sym_val_to_name[SYM_TYPES]
211#define p_user_val_to_name sym_val_to_name[SYM_USERS]
212#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS]
213#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS]
214#define p_cat_val_to_name sym_val_to_name[SYM_CATS]
215 207
216 /* class, role, and user attributes indexed by (value - 1) */ 208 /* class, role, and user attributes indexed by (value - 1) */
217 struct class_datum **class_val_to_struct; 209 struct class_datum **class_val_to_struct;
218 struct role_datum **role_val_to_struct; 210 struct role_datum **role_val_to_struct;
219 struct user_datum **user_val_to_struct; 211 struct user_datum **user_val_to_struct;
220 struct type_datum **type_val_to_struct; 212 struct flex_array *type_val_to_struct_array;
221 213
222 /* type enforcement access vectors and transitions */ 214 /* type enforcement access vectors and transitions */
223 struct avtab te_avtab; 215 struct avtab te_avtab;
@@ -321,6 +313,13 @@ static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file
321 return 0; 313 return 0;
322} 314}
323 315
316static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr)
317{
318 struct flex_array *fa = p->sym_val_to_name[sym_num];
319
320 return flex_array_get_ptr(fa, element_nr);
321}
322
324extern u16 string_to_security_class(struct policydb *p, const char *name); 323extern u16 string_to_security_class(struct policydb *p, const char *name);
325extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); 324extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
326 325
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 223c1ff6ef23..a03cfaf0ee07 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -464,7 +464,7 @@ static void security_dump_masked_av(struct context *scontext,
464 if (!permissions) 464 if (!permissions)
465 return; 465 return;
466 466
467 tclass_name = policydb.p_class_val_to_name[tclass - 1]; 467 tclass_name = sym_name(&policydb, SYM_CLASSES, tclass - 1);
468 tclass_dat = policydb.class_val_to_struct[tclass - 1]; 468 tclass_dat = policydb.class_val_to_struct[tclass - 1];
469 common_dat = tclass_dat->comdatum; 469 common_dat = tclass_dat->comdatum;
470 470
@@ -530,12 +530,18 @@ static void type_attribute_bounds_av(struct context *scontext,
530 struct context lo_scontext; 530 struct context lo_scontext;
531 struct context lo_tcontext; 531 struct context lo_tcontext;
532 struct av_decision lo_avd; 532 struct av_decision lo_avd;
533 struct type_datum *source 533 struct type_datum *source;
534 = policydb.type_val_to_struct[scontext->type - 1]; 534 struct type_datum *target;
535 struct type_datum *target
536 = policydb.type_val_to_struct[tcontext->type - 1];
537 u32 masked = 0; 535 u32 masked = 0;
538 536
537 source = flex_array_get_ptr(policydb.type_val_to_struct_array,
538 scontext->type - 1);
539 BUG_ON(!source);
540
541 target = flex_array_get_ptr(policydb.type_val_to_struct_array,
542 tcontext->type - 1);
543 BUG_ON(!target);
544
539 if (source->bounds) { 545 if (source->bounds) {
540 memset(&lo_avd, 0, sizeof(lo_avd)); 546 memset(&lo_avd, 0, sizeof(lo_avd));
541 547
@@ -701,16 +707,16 @@ static int security_validtrans_handle_fail(struct context *ocontext,
701 char *o = NULL, *n = NULL, *t = NULL; 707 char *o = NULL, *n = NULL, *t = NULL;
702 u32 olen, nlen, tlen; 708 u32 olen, nlen, tlen;
703 709
704 if (context_struct_to_string(ocontext, &o, &olen) < 0) 710 if (context_struct_to_string(ocontext, &o, &olen))
705 goto out; 711 goto out;
706 if (context_struct_to_string(ncontext, &n, &nlen) < 0) 712 if (context_struct_to_string(ncontext, &n, &nlen))
707 goto out; 713 goto out;
708 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 714 if (context_struct_to_string(tcontext, &t, &tlen))
709 goto out; 715 goto out;
710 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 716 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
711 "security_validate_transition: denied for" 717 "security_validate_transition: denied for"
712 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", 718 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
713 o, n, t, policydb.p_class_val_to_name[tclass-1]); 719 o, n, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
714out: 720out:
715 kfree(o); 721 kfree(o);
716 kfree(n); 722 kfree(n);
@@ -801,10 +807,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
801 struct context *old_context, *new_context; 807 struct context *old_context, *new_context;
802 struct type_datum *type; 808 struct type_datum *type;
803 int index; 809 int index;
804 int rc = -EINVAL; 810 int rc;
805 811
806 read_lock(&policy_rwlock); 812 read_lock(&policy_rwlock);
807 813
814 rc = -EINVAL;
808 old_context = sidtab_search(&sidtab, old_sid); 815 old_context = sidtab_search(&sidtab, old_sid);
809 if (!old_context) { 816 if (!old_context) {
810 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 817 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -812,6 +819,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
812 goto out; 819 goto out;
813 } 820 }
814 821
822 rc = -EINVAL;
815 new_context = sidtab_search(&sidtab, new_sid); 823 new_context = sidtab_search(&sidtab, new_sid);
816 if (!new_context) { 824 if (!new_context) {
817 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 825 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -819,28 +827,27 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
819 goto out; 827 goto out;
820 } 828 }
821 829
830 rc = 0;
822 /* type/domain unchanged */ 831 /* type/domain unchanged */
823 if (old_context->type == new_context->type) { 832 if (old_context->type == new_context->type)
824 rc = 0;
825 goto out; 833 goto out;
826 }
827 834
828 index = new_context->type; 835 index = new_context->type;
829 while (true) { 836 while (true) {
830 type = policydb.type_val_to_struct[index - 1]; 837 type = flex_array_get_ptr(policydb.type_val_to_struct_array,
838 index - 1);
831 BUG_ON(!type); 839 BUG_ON(!type);
832 840
833 /* not bounded anymore */ 841 /* not bounded anymore */
834 if (!type->bounds) { 842 rc = -EPERM;
835 rc = -EPERM; 843 if (!type->bounds)
836 break; 844 break;
837 }
838 845
839 /* @newsid is bounded by @oldsid */ 846 /* @newsid is bounded by @oldsid */
840 if (type->bounds == old_context->type) { 847 rc = 0;
841 rc = 0; 848 if (type->bounds == old_context->type)
842 break; 849 break;
843 } 850
844 index = type->bounds; 851 index = type->bounds;
845 } 852 }
846 853
@@ -1005,9 +1012,9 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1005 } 1012 }
1006 1013
1007 /* Compute the size of the context. */ 1014 /* Compute the size of the context. */
1008 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; 1015 *scontext_len += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + 1;
1009 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; 1016 *scontext_len += strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + 1;
1010 *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; 1017 *scontext_len += strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)) + 1;
1011 *scontext_len += mls_compute_context_len(context); 1018 *scontext_len += mls_compute_context_len(context);
1012 1019
1013 if (!scontext) 1020 if (!scontext)
@@ -1023,12 +1030,12 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1023 * Copy the user name, role name and type name into the context. 1030 * Copy the user name, role name and type name into the context.
1024 */ 1031 */
1025 sprintf(scontextp, "%s:%s:%s", 1032 sprintf(scontextp, "%s:%s:%s",
1026 policydb.p_user_val_to_name[context->user - 1], 1033 sym_name(&policydb, SYM_USERS, context->user - 1),
1027 policydb.p_role_val_to_name[context->role - 1], 1034 sym_name(&policydb, SYM_ROLES, context->role - 1),
1028 policydb.p_type_val_to_name[context->type - 1]); 1035 sym_name(&policydb, SYM_TYPES, context->type - 1));
1029 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1036 scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) +
1030 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + 1037 1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) +
1031 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); 1038 1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1));
1032 1039
1033 mls_sid_to_context(context, &scontextp); 1040 mls_sid_to_context(context, &scontextp);
1034 1041
@@ -1187,16 +1194,13 @@ static int string_to_context_struct(struct policydb *pol,
1187 if (rc) 1194 if (rc)
1188 goto out; 1195 goto out;
1189 1196
1190 if ((p - scontext) < scontext_len) { 1197 rc = -EINVAL;
1191 rc = -EINVAL; 1198 if ((p - scontext) < scontext_len)
1192 goto out; 1199 goto out;
1193 }
1194 1200
1195 /* Check the validity of the new context. */ 1201 /* Check the validity of the new context. */
1196 if (!policydb_context_isvalid(pol, ctx)) { 1202 if (!policydb_context_isvalid(pol, ctx))
1197 rc = -EINVAL;
1198 goto out; 1203 goto out;
1199 }
1200 rc = 0; 1204 rc = 0;
1201out: 1205out:
1202 if (rc) 1206 if (rc)
@@ -1235,27 +1239,26 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1235 1239
1236 if (force) { 1240 if (force) {
1237 /* Save another copy for storing in uninterpreted form */ 1241 /* Save another copy for storing in uninterpreted form */
1242 rc = -ENOMEM;
1238 str = kstrdup(scontext2, gfp_flags); 1243 str = kstrdup(scontext2, gfp_flags);
1239 if (!str) { 1244 if (!str)
1240 kfree(scontext2); 1245 goto out;
1241 return -ENOMEM;
1242 }
1243 } 1246 }
1244 1247
1245 read_lock(&policy_rwlock); 1248 read_lock(&policy_rwlock);
1246 rc = string_to_context_struct(&policydb, &sidtab, 1249 rc = string_to_context_struct(&policydb, &sidtab, scontext2,
1247 scontext2, scontext_len, 1250 scontext_len, &context, def_sid);
1248 &context, def_sid);
1249 if (rc == -EINVAL && force) { 1251 if (rc == -EINVAL && force) {
1250 context.str = str; 1252 context.str = str;
1251 context.len = scontext_len; 1253 context.len = scontext_len;
1252 str = NULL; 1254 str = NULL;
1253 } else if (rc) 1255 } else if (rc)
1254 goto out; 1256 goto out_unlock;
1255 rc = sidtab_context_to_sid(&sidtab, &context, sid); 1257 rc = sidtab_context_to_sid(&sidtab, &context, sid);
1256 context_destroy(&context); 1258 context_destroy(&context);
1257out: 1259out_unlock:
1258 read_unlock(&policy_rwlock); 1260 read_unlock(&policy_rwlock);
1261out:
1259 kfree(scontext2); 1262 kfree(scontext2);
1260 kfree(str); 1263 kfree(str);
1261 return rc; 1264 return rc;
@@ -1319,18 +1322,18 @@ static int compute_sid_handle_invalid_context(
1319 char *s = NULL, *t = NULL, *n = NULL; 1322 char *s = NULL, *t = NULL, *n = NULL;
1320 u32 slen, tlen, nlen; 1323 u32 slen, tlen, nlen;
1321 1324
1322 if (context_struct_to_string(scontext, &s, &slen) < 0) 1325 if (context_struct_to_string(scontext, &s, &slen))
1323 goto out; 1326 goto out;
1324 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 1327 if (context_struct_to_string(tcontext, &t, &tlen))
1325 goto out; 1328 goto out;
1326 if (context_struct_to_string(newcontext, &n, &nlen) < 0) 1329 if (context_struct_to_string(newcontext, &n, &nlen))
1327 goto out; 1330 goto out;
1328 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 1331 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1329 "security_compute_sid: invalid context %s" 1332 "security_compute_sid: invalid context %s"
1330 " for scontext=%s" 1333 " for scontext=%s"
1331 " tcontext=%s" 1334 " tcontext=%s"
1332 " tclass=%s", 1335 " tclass=%s",
1333 n, s, t, policydb.p_class_val_to_name[tclass-1]); 1336 n, s, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
1334out: 1337out:
1335 kfree(s); 1338 kfree(s);
1336 kfree(t); 1339 kfree(t);
@@ -1569,22 +1572,17 @@ static int clone_sid(u32 sid,
1569 1572
1570static inline int convert_context_handle_invalid_context(struct context *context) 1573static inline int convert_context_handle_invalid_context(struct context *context)
1571{ 1574{
1572 int rc = 0; 1575 char *s;
1576 u32 len;
1573 1577
1574 if (selinux_enforcing) { 1578 if (selinux_enforcing)
1575 rc = -EINVAL; 1579 return -EINVAL;
1576 } else { 1580
1577 char *s; 1581 if (!context_struct_to_string(context, &s, &len)) {
1578 u32 len; 1582 printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s);
1579 1583 kfree(s);
1580 if (!context_struct_to_string(context, &s, &len)) {
1581 printk(KERN_WARNING
1582 "SELinux: Context %s would be invalid if enforcing\n",
1583 s);
1584 kfree(s);
1585 }
1586 } 1584 }
1587 return rc; 1585 return 0;
1588} 1586}
1589 1587
1590struct convert_context_args { 1588struct convert_context_args {
@@ -1621,17 +1619,17 @@ static int convert_context(u32 key,
1621 1619
1622 if (c->str) { 1620 if (c->str) {
1623 struct context ctx; 1621 struct context ctx;
1622
1623 rc = -ENOMEM;
1624 s = kstrdup(c->str, GFP_KERNEL); 1624 s = kstrdup(c->str, GFP_KERNEL);
1625 if (!s) { 1625 if (!s)
1626 rc = -ENOMEM;
1627 goto out; 1626 goto out;
1628 } 1627
1629 rc = string_to_context_struct(args->newp, NULL, s, 1628 rc = string_to_context_struct(args->newp, NULL, s,
1630 c->len, &ctx, SECSID_NULL); 1629 c->len, &ctx, SECSID_NULL);
1631 kfree(s); 1630 kfree(s);
1632 if (!rc) { 1631 if (!rc) {
1633 printk(KERN_INFO 1632 printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n",
1634 "SELinux: Context %s became valid (mapped).\n",
1635 c->str); 1633 c->str);
1636 /* Replace string with mapped representation. */ 1634 /* Replace string with mapped representation. */
1637 kfree(c->str); 1635 kfree(c->str);
@@ -1643,8 +1641,7 @@ static int convert_context(u32 key,
1643 goto out; 1641 goto out;
1644 } else { 1642 } else {
1645 /* Other error condition, e.g. ENOMEM. */ 1643 /* Other error condition, e.g. ENOMEM. */
1646 printk(KERN_ERR 1644 printk(KERN_ERR "SELinux: Unable to map context %s, rc = %d.\n",
1647 "SELinux: Unable to map context %s, rc = %d.\n",
1648 c->str, -rc); 1645 c->str, -rc);
1649 goto out; 1646 goto out;
1650 } 1647 }
@@ -1654,25 +1651,26 @@ static int convert_context(u32 key,
1654 if (rc) 1651 if (rc)
1655 goto out; 1652 goto out;
1656 1653
1657 rc = -EINVAL;
1658
1659 /* Convert the user. */ 1654 /* Convert the user. */
1655 rc = -EINVAL;
1660 usrdatum = hashtab_search(args->newp->p_users.table, 1656 usrdatum = hashtab_search(args->newp->p_users.table,
1661 args->oldp->p_user_val_to_name[c->user - 1]); 1657 sym_name(args->oldp, SYM_USERS, c->user - 1));
1662 if (!usrdatum) 1658 if (!usrdatum)
1663 goto bad; 1659 goto bad;
1664 c->user = usrdatum->value; 1660 c->user = usrdatum->value;
1665 1661
1666 /* Convert the role. */ 1662 /* Convert the role. */
1663 rc = -EINVAL;
1667 role = hashtab_search(args->newp->p_roles.table, 1664 role = hashtab_search(args->newp->p_roles.table,
1668 args->oldp->p_role_val_to_name[c->role - 1]); 1665 sym_name(args->oldp, SYM_ROLES, c->role - 1));
1669 if (!role) 1666 if (!role)
1670 goto bad; 1667 goto bad;
1671 c->role = role->value; 1668 c->role = role->value;
1672 1669
1673 /* Convert the type. */ 1670 /* Convert the type. */
1671 rc = -EINVAL;
1674 typdatum = hashtab_search(args->newp->p_types.table, 1672 typdatum = hashtab_search(args->newp->p_types.table,
1675 args->oldp->p_type_val_to_name[c->type - 1]); 1673 sym_name(args->oldp, SYM_TYPES, c->type - 1));
1676 if (!typdatum) 1674 if (!typdatum)
1677 goto bad; 1675 goto bad;
1678 c->type = typdatum->value; 1676 c->type = typdatum->value;
@@ -1700,6 +1698,7 @@ static int convert_context(u32 key,
1700 oc = args->newp->ocontexts[OCON_ISID]; 1698 oc = args->newp->ocontexts[OCON_ISID];
1701 while (oc && oc->sid[0] != SECINITSID_UNLABELED) 1699 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1702 oc = oc->next; 1700 oc = oc->next;
1701 rc = -EINVAL;
1703 if (!oc) { 1702 if (!oc) {
1704 printk(KERN_ERR "SELinux: unable to look up" 1703 printk(KERN_ERR "SELinux: unable to look up"
1705 " the initial SIDs list\n"); 1704 " the initial SIDs list\n");
@@ -1719,19 +1718,20 @@ static int convert_context(u32 key,
1719 } 1718 }
1720 1719
1721 context_destroy(&oldc); 1720 context_destroy(&oldc);
1721
1722 rc = 0; 1722 rc = 0;
1723out: 1723out:
1724 return rc; 1724 return rc;
1725bad: 1725bad:
1726 /* Map old representation to string and save it. */ 1726 /* Map old representation to string and save it. */
1727 if (context_struct_to_string(&oldc, &s, &len)) 1727 rc = context_struct_to_string(&oldc, &s, &len);
1728 return -ENOMEM; 1728 if (rc)
1729 return rc;
1729 context_destroy(&oldc); 1730 context_destroy(&oldc);
1730 context_destroy(c); 1731 context_destroy(c);
1731 c->str = s; 1732 c->str = s;
1732 c->len = len; 1733 c->len = len;
1733 printk(KERN_INFO 1734 printk(KERN_INFO "SELinux: Context %s became invalid (unmapped).\n",
1734 "SELinux: Context %s became invalid (unmapped).\n",
1735 c->str); 1735 c->str);
1736 rc = 0; 1736 rc = 0;
1737 goto out; 1737 goto out;
@@ -2012,7 +2012,7 @@ int security_node_sid(u16 domain,
2012 u32 addrlen, 2012 u32 addrlen,
2013 u32 *out_sid) 2013 u32 *out_sid)
2014{ 2014{
2015 int rc = 0; 2015 int rc;
2016 struct ocontext *c; 2016 struct ocontext *c;
2017 2017
2018 read_lock(&policy_rwlock); 2018 read_lock(&policy_rwlock);
@@ -2021,10 +2021,9 @@ int security_node_sid(u16 domain,
2021 case AF_INET: { 2021 case AF_INET: {
2022 u32 addr; 2022 u32 addr;
2023 2023
2024 if (addrlen != sizeof(u32)) { 2024 rc = -EINVAL;
2025 rc = -EINVAL; 2025 if (addrlen != sizeof(u32))
2026 goto out; 2026 goto out;
2027 }
2028 2027
2029 addr = *((u32 *)addrp); 2028 addr = *((u32 *)addrp);
2030 2029
@@ -2038,10 +2037,9 @@ int security_node_sid(u16 domain,
2038 } 2037 }
2039 2038
2040 case AF_INET6: 2039 case AF_INET6:
2041 if (addrlen != sizeof(u64) * 2) { 2040 rc = -EINVAL;
2042 rc = -EINVAL; 2041 if (addrlen != sizeof(u64) * 2)
2043 goto out; 2042 goto out;
2044 }
2045 c = policydb.ocontexts[OCON_NODE6]; 2043 c = policydb.ocontexts[OCON_NODE6];
2046 while (c) { 2044 while (c) {
2047 if (match_ipv6_addrmask(addrp, c->u.node6.addr, 2045 if (match_ipv6_addrmask(addrp, c->u.node6.addr,
@@ -2052,6 +2050,7 @@ int security_node_sid(u16 domain,
2052 break; 2050 break;
2053 2051
2054 default: 2052 default:
2053 rc = 0;
2055 *out_sid = SECINITSID_NODE; 2054 *out_sid = SECINITSID_NODE;
2056 goto out; 2055 goto out;
2057 } 2056 }
@@ -2069,6 +2068,7 @@ int security_node_sid(u16 domain,
2069 *out_sid = SECINITSID_NODE; 2068 *out_sid = SECINITSID_NODE;
2070 } 2069 }
2071 2070
2071 rc = 0;
2072out: 2072out:
2073 read_unlock(&policy_rwlock); 2073 read_unlock(&policy_rwlock);
2074 return rc; 2074 return rc;
@@ -2113,24 +2113,22 @@ int security_get_user_sids(u32 fromsid,
2113 2113
2114 context_init(&usercon); 2114 context_init(&usercon);
2115 2115
2116 rc = -EINVAL;
2116 fromcon = sidtab_search(&sidtab, fromsid); 2117 fromcon = sidtab_search(&sidtab, fromsid);
2117 if (!fromcon) { 2118 if (!fromcon)
2118 rc = -EINVAL;
2119 goto out_unlock; 2119 goto out_unlock;
2120 }
2121 2120
2121 rc = -EINVAL;
2122 user = hashtab_search(policydb.p_users.table, username); 2122 user = hashtab_search(policydb.p_users.table, username);
2123 if (!user) { 2123 if (!user)
2124 rc = -EINVAL;
2125 goto out_unlock; 2124 goto out_unlock;
2126 } 2125
2127 usercon.user = user->value; 2126 usercon.user = user->value;
2128 2127
2128 rc = -ENOMEM;
2129 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); 2129 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
2130 if (!mysids) { 2130 if (!mysids)
2131 rc = -ENOMEM;
2132 goto out_unlock; 2131 goto out_unlock;
2133 }
2134 2132
2135 ebitmap_for_each_positive_bit(&user->roles, rnode, i) { 2133 ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
2136 role = policydb.role_val_to_struct[i]; 2134 role = policydb.role_val_to_struct[i];
@@ -2147,12 +2145,11 @@ int security_get_user_sids(u32 fromsid,
2147 if (mynel < maxnel) { 2145 if (mynel < maxnel) {
2148 mysids[mynel++] = sid; 2146 mysids[mynel++] = sid;
2149 } else { 2147 } else {
2148 rc = -ENOMEM;
2150 maxnel += SIDS_NEL; 2149 maxnel += SIDS_NEL;
2151 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); 2150 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
2152 if (!mysids2) { 2151 if (!mysids2)
2153 rc = -ENOMEM;
2154 goto out_unlock; 2152 goto out_unlock;
2155 }
2156 memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); 2153 memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
2157 kfree(mysids); 2154 kfree(mysids);
2158 mysids = mysids2; 2155 mysids = mysids2;
@@ -2160,7 +2157,7 @@ int security_get_user_sids(u32 fromsid,
2160 } 2157 }
2161 } 2158 }
2162 } 2159 }
2163 2160 rc = 0;
2164out_unlock: 2161out_unlock:
2165 read_unlock(&policy_rwlock); 2162 read_unlock(&policy_rwlock);
2166 if (rc || !mynel) { 2163 if (rc || !mynel) {
@@ -2168,9 +2165,9 @@ out_unlock:
2168 goto out; 2165 goto out;
2169 } 2166 }
2170 2167
2168 rc = -ENOMEM;
2171 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); 2169 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
2172 if (!mysids2) { 2170 if (!mysids2) {
2173 rc = -ENOMEM;
2174 kfree(mysids); 2171 kfree(mysids);
2175 goto out; 2172 goto out;
2176 } 2173 }
@@ -2211,7 +2208,7 @@ int security_genfs_sid(const char *fstype,
2211 u16 sclass; 2208 u16 sclass;
2212 struct genfs *genfs; 2209 struct genfs *genfs;
2213 struct ocontext *c; 2210 struct ocontext *c;
2214 int rc = 0, cmp = 0; 2211 int rc, cmp = 0;
2215 2212
2216 while (path[0] == '/' && path[1] == '/') 2213 while (path[0] == '/' && path[1] == '/')
2217 path++; 2214 path++;
@@ -2219,6 +2216,7 @@ int security_genfs_sid(const char *fstype,
2219 read_lock(&policy_rwlock); 2216 read_lock(&policy_rwlock);
2220 2217
2221 sclass = unmap_class(orig_sclass); 2218 sclass = unmap_class(orig_sclass);
2219 *sid = SECINITSID_UNLABELED;
2222 2220
2223 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2221 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2224 cmp = strcmp(fstype, genfs->fstype); 2222 cmp = strcmp(fstype, genfs->fstype);
@@ -2226,11 +2224,9 @@ int security_genfs_sid(const char *fstype,
2226 break; 2224 break;
2227 } 2225 }
2228 2226
2229 if (!genfs || cmp) { 2227 rc = -ENOENT;
2230 *sid = SECINITSID_UNLABELED; 2228 if (!genfs || cmp)
2231 rc = -ENOENT;
2232 goto out; 2229 goto out;
2233 }
2234 2230
2235 for (c = genfs->head; c; c = c->next) { 2231 for (c = genfs->head; c; c = c->next) {
2236 len = strlen(c->u.name); 2232 len = strlen(c->u.name);
@@ -2239,21 +2235,18 @@ int security_genfs_sid(const char *fstype,
2239 break; 2235 break;
2240 } 2236 }
2241 2237
2242 if (!c) { 2238 rc = -ENOENT;
2243 *sid = SECINITSID_UNLABELED; 2239 if (!c)
2244 rc = -ENOENT;
2245 goto out; 2240 goto out;
2246 }
2247 2241
2248 if (!c->sid[0]) { 2242 if (!c->sid[0]) {
2249 rc = sidtab_context_to_sid(&sidtab, 2243 rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]);
2250 &c->context[0],
2251 &c->sid[0]);
2252 if (rc) 2244 if (rc)
2253 goto out; 2245 goto out;
2254 } 2246 }
2255 2247
2256 *sid = c->sid[0]; 2248 *sid = c->sid[0];
2249 rc = 0;
2257out: 2250out:
2258 read_unlock(&policy_rwlock); 2251 read_unlock(&policy_rwlock);
2259 return rc; 2252 return rc;
@@ -2285,8 +2278,7 @@ int security_fs_use(
2285 if (c) { 2278 if (c) {
2286 *behavior = c->v.behavior; 2279 *behavior = c->v.behavior;
2287 if (!c->sid[0]) { 2280 if (!c->sid[0]) {
2288 rc = sidtab_context_to_sid(&sidtab, 2281 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2289 &c->context[0],
2290 &c->sid[0]); 2282 &c->sid[0]);
2291 if (rc) 2283 if (rc)
2292 goto out; 2284 goto out;
@@ -2309,34 +2301,39 @@ out:
2309 2301
2310int security_get_bools(int *len, char ***names, int **values) 2302int security_get_bools(int *len, char ***names, int **values)
2311{ 2303{
2312 int i, rc = -ENOMEM; 2304 int i, rc;
2313 2305
2314 read_lock(&policy_rwlock); 2306 read_lock(&policy_rwlock);
2315 *names = NULL; 2307 *names = NULL;
2316 *values = NULL; 2308 *values = NULL;
2317 2309
2310 rc = 0;
2318 *len = policydb.p_bools.nprim; 2311 *len = policydb.p_bools.nprim;
2319 if (!*len) { 2312 if (!*len)
2320 rc = 0;
2321 goto out; 2313 goto out;
2322 }
2323 2314
2324 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); 2315 rc = -ENOMEM;
2316 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC);
2325 if (!*names) 2317 if (!*names)
2326 goto err; 2318 goto err;
2327 2319
2328 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); 2320 rc = -ENOMEM;
2321 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
2329 if (!*values) 2322 if (!*values)
2330 goto err; 2323 goto err;
2331 2324
2332 for (i = 0; i < *len; i++) { 2325 for (i = 0; i < *len; i++) {
2333 size_t name_len; 2326 size_t name_len;
2327
2334 (*values)[i] = policydb.bool_val_to_struct[i]->state; 2328 (*values)[i] = policydb.bool_val_to_struct[i]->state;
2335 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 2329 name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1;
2336 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 2330
2331 rc = -ENOMEM;
2332 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
2337 if (!(*names)[i]) 2333 if (!(*names)[i])
2338 goto err; 2334 goto err;
2339 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 2335
2336 strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len);
2340 (*names)[i][name_len - 1] = 0; 2337 (*names)[i][name_len - 1] = 0;
2341 } 2338 }
2342 rc = 0; 2339 rc = 0;
@@ -2355,24 +2352,23 @@ err:
2355 2352
2356int security_set_bools(int len, int *values) 2353int security_set_bools(int len, int *values)
2357{ 2354{
2358 int i, rc = 0; 2355 int i, rc;
2359 int lenp, seqno = 0; 2356 int lenp, seqno = 0;
2360 struct cond_node *cur; 2357 struct cond_node *cur;
2361 2358
2362 write_lock_irq(&policy_rwlock); 2359 write_lock_irq(&policy_rwlock);
2363 2360
2361 rc = -EFAULT;
2364 lenp = policydb.p_bools.nprim; 2362 lenp = policydb.p_bools.nprim;
2365 if (len != lenp) { 2363 if (len != lenp)
2366 rc = -EFAULT;
2367 goto out; 2364 goto out;
2368 }
2369 2365
2370 for (i = 0; i < len; i++) { 2366 for (i = 0; i < len; i++) {
2371 if (!!values[i] != policydb.bool_val_to_struct[i]->state) { 2367 if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
2372 audit_log(current->audit_context, GFP_ATOMIC, 2368 audit_log(current->audit_context, GFP_ATOMIC,
2373 AUDIT_MAC_CONFIG_CHANGE, 2369 AUDIT_MAC_CONFIG_CHANGE,
2374 "bool=%s val=%d old_val=%d auid=%u ses=%u", 2370 "bool=%s val=%d old_val=%d auid=%u ses=%u",
2375 policydb.p_bool_val_to_name[i], 2371 sym_name(&policydb, SYM_BOOLS, i),
2376 !!values[i], 2372 !!values[i],
2377 policydb.bool_val_to_struct[i]->state, 2373 policydb.bool_val_to_struct[i]->state,
2378 audit_get_loginuid(current), 2374 audit_get_loginuid(current),
@@ -2391,7 +2387,7 @@ int security_set_bools(int len, int *values)
2391 } 2387 }
2392 2388
2393 seqno = ++latest_granting; 2389 seqno = ++latest_granting;
2394 2390 rc = 0;
2395out: 2391out:
2396 write_unlock_irq(&policy_rwlock); 2392 write_unlock_irq(&policy_rwlock);
2397 if (!rc) { 2393 if (!rc) {
@@ -2405,16 +2401,15 @@ out:
2405 2401
2406int security_get_bool_value(int bool) 2402int security_get_bool_value(int bool)
2407{ 2403{
2408 int rc = 0; 2404 int rc;
2409 int len; 2405 int len;
2410 2406
2411 read_lock(&policy_rwlock); 2407 read_lock(&policy_rwlock);
2412 2408
2409 rc = -EFAULT;
2413 len = policydb.p_bools.nprim; 2410 len = policydb.p_bools.nprim;
2414 if (bool >= len) { 2411 if (bool >= len)
2415 rc = -EFAULT;
2416 goto out; 2412 goto out;
2417 }
2418 2413
2419 rc = policydb.bool_val_to_struct[bool]->state; 2414 rc = policydb.bool_val_to_struct[bool]->state;
2420out: 2415out:
@@ -2464,8 +2459,9 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2464 struct context newcon; 2459 struct context newcon;
2465 char *s; 2460 char *s;
2466 u32 len; 2461 u32 len;
2467 int rc = 0; 2462 int rc;
2468 2463
2464 rc = 0;
2469 if (!ss_initialized || !policydb.mls_enabled) { 2465 if (!ss_initialized || !policydb.mls_enabled) {
2470 *new_sid = sid; 2466 *new_sid = sid;
2471 goto out; 2467 goto out;
@@ -2474,19 +2470,20 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2474 context_init(&newcon); 2470 context_init(&newcon);
2475 2471
2476 read_lock(&policy_rwlock); 2472 read_lock(&policy_rwlock);
2473
2474 rc = -EINVAL;
2477 context1 = sidtab_search(&sidtab, sid); 2475 context1 = sidtab_search(&sidtab, sid);
2478 if (!context1) { 2476 if (!context1) {
2479 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2477 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2480 __func__, sid); 2478 __func__, sid);
2481 rc = -EINVAL;
2482 goto out_unlock; 2479 goto out_unlock;
2483 } 2480 }
2484 2481
2482 rc = -EINVAL;
2485 context2 = sidtab_search(&sidtab, mls_sid); 2483 context2 = sidtab_search(&sidtab, mls_sid);
2486 if (!context2) { 2484 if (!context2) {
2487 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2485 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2488 __func__, mls_sid); 2486 __func__, mls_sid);
2489 rc = -EINVAL;
2490 goto out_unlock; 2487 goto out_unlock;
2491 } 2488 }
2492 2489
@@ -2500,20 +2497,17 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2500 /* Check the validity of the new context. */ 2497 /* Check the validity of the new context. */
2501 if (!policydb_context_isvalid(&policydb, &newcon)) { 2498 if (!policydb_context_isvalid(&policydb, &newcon)) {
2502 rc = convert_context_handle_invalid_context(&newcon); 2499 rc = convert_context_handle_invalid_context(&newcon);
2503 if (rc) 2500 if (rc) {
2504 goto bad; 2501 if (!context_struct_to_string(&newcon, &s, &len)) {
2502 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2503 "security_sid_mls_copy: invalid context %s", s);
2504 kfree(s);
2505 }
2506 goto out_unlock;
2507 }
2505 } 2508 }
2506 2509
2507 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); 2510 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
2508 goto out_unlock;
2509
2510bad:
2511 if (!context_struct_to_string(&newcon, &s, &len)) {
2512 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2513 "security_sid_mls_copy: invalid context %s", s);
2514 kfree(s);
2515 }
2516
2517out_unlock: 2511out_unlock:
2518 read_unlock(&policy_rwlock); 2512 read_unlock(&policy_rwlock);
2519 context_destroy(&newcon); 2513 context_destroy(&newcon);
@@ -2549,6 +2543,8 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2549 struct context *nlbl_ctx; 2543 struct context *nlbl_ctx;
2550 struct context *xfrm_ctx; 2544 struct context *xfrm_ctx;
2551 2545
2546 *peer_sid = SECSID_NULL;
2547
2552 /* handle the common (which also happens to be the set of easy) cases 2548 /* handle the common (which also happens to be the set of easy) cases
2553 * right away, these two if statements catch everything involving a 2549 * right away, these two if statements catch everything involving a
2554 * single or absent peer SID/label */ 2550 * single or absent peer SID/label */
@@ -2567,40 +2563,37 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2567 /* we don't need to check ss_initialized here since the only way both 2563 /* we don't need to check ss_initialized here since the only way both
2568 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2564 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2569 * security server was initialized and ss_initialized was true */ 2565 * security server was initialized and ss_initialized was true */
2570 if (!policydb.mls_enabled) { 2566 if (!policydb.mls_enabled)
2571 *peer_sid = SECSID_NULL;
2572 return 0; 2567 return 0;
2573 }
2574 2568
2575 read_lock(&policy_rwlock); 2569 read_lock(&policy_rwlock);
2576 2570
2571 rc = -EINVAL;
2577 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); 2572 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
2578 if (!nlbl_ctx) { 2573 if (!nlbl_ctx) {
2579 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2574 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2580 __func__, nlbl_sid); 2575 __func__, nlbl_sid);
2581 rc = -EINVAL; 2576 goto out;
2582 goto out_slowpath;
2583 } 2577 }
2578 rc = -EINVAL;
2584 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); 2579 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid);
2585 if (!xfrm_ctx) { 2580 if (!xfrm_ctx) {
2586 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2581 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2587 __func__, xfrm_sid); 2582 __func__, xfrm_sid);
2588 rc = -EINVAL; 2583 goto out;
2589 goto out_slowpath;
2590 } 2584 }
2591 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); 2585 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES);
2586 if (rc)
2587 goto out;
2592 2588
2593out_slowpath: 2589 /* at present NetLabel SIDs/labels really only carry MLS
2590 * information so if the MLS portion of the NetLabel SID
2591 * matches the MLS portion of the labeled XFRM SID/label
2592 * then pass along the XFRM SID as it is the most
2593 * expressive */
2594 *peer_sid = xfrm_sid;
2595out:
2594 read_unlock(&policy_rwlock); 2596 read_unlock(&policy_rwlock);
2595 if (rc == 0)
2596 /* at present NetLabel SIDs/labels really only carry MLS
2597 * information so if the MLS portion of the NetLabel SID
2598 * matches the MLS portion of the labeled XFRM SID/label
2599 * then pass along the XFRM SID as it is the most
2600 * expressive */
2601 *peer_sid = xfrm_sid;
2602 else
2603 *peer_sid = SECSID_NULL;
2604 return rc; 2597 return rc;
2605} 2598}
2606 2599
@@ -2619,10 +2612,11 @@ static int get_classes_callback(void *k, void *d, void *args)
2619 2612
2620int security_get_classes(char ***classes, int *nclasses) 2613int security_get_classes(char ***classes, int *nclasses)
2621{ 2614{
2622 int rc = -ENOMEM; 2615 int rc;
2623 2616
2624 read_lock(&policy_rwlock); 2617 read_lock(&policy_rwlock);
2625 2618
2619 rc = -ENOMEM;
2626 *nclasses = policydb.p_classes.nprim; 2620 *nclasses = policydb.p_classes.nprim;
2627 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); 2621 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2628 if (!*classes) 2622 if (!*classes)
@@ -2630,7 +2624,7 @@ int security_get_classes(char ***classes, int *nclasses)
2630 2624
2631 rc = hashtab_map(policydb.p_classes.table, get_classes_callback, 2625 rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
2632 *classes); 2626 *classes);
2633 if (rc < 0) { 2627 if (rc) {
2634 int i; 2628 int i;
2635 for (i = 0; i < *nclasses; i++) 2629 for (i = 0; i < *nclasses; i++)
2636 kfree((*classes)[i]); 2630 kfree((*classes)[i]);
@@ -2657,19 +2651,20 @@ static int get_permissions_callback(void *k, void *d, void *args)
2657 2651
2658int security_get_permissions(char *class, char ***perms, int *nperms) 2652int security_get_permissions(char *class, char ***perms, int *nperms)
2659{ 2653{
2660 int rc = -ENOMEM, i; 2654 int rc, i;
2661 struct class_datum *match; 2655 struct class_datum *match;
2662 2656
2663 read_lock(&policy_rwlock); 2657 read_lock(&policy_rwlock);
2664 2658
2659 rc = -EINVAL;
2665 match = hashtab_search(policydb.p_classes.table, class); 2660 match = hashtab_search(policydb.p_classes.table, class);
2666 if (!match) { 2661 if (!match) {
2667 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", 2662 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n",
2668 __func__, class); 2663 __func__, class);
2669 rc = -EINVAL;
2670 goto out; 2664 goto out;
2671 } 2665 }
2672 2666
2667 rc = -ENOMEM;
2673 *nperms = match->permissions.nprim; 2668 *nperms = match->permissions.nprim;
2674 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); 2669 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2675 if (!*perms) 2670 if (!*perms)
@@ -2678,13 +2673,13 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2678 if (match->comdatum) { 2673 if (match->comdatum) {
2679 rc = hashtab_map(match->comdatum->permissions.table, 2674 rc = hashtab_map(match->comdatum->permissions.table,
2680 get_permissions_callback, *perms); 2675 get_permissions_callback, *perms);
2681 if (rc < 0) 2676 if (rc)
2682 goto err; 2677 goto err;
2683 } 2678 }
2684 2679
2685 rc = hashtab_map(match->permissions.table, get_permissions_callback, 2680 rc = hashtab_map(match->permissions.table, get_permissions_callback,
2686 *perms); 2681 *perms);
2687 if (rc < 0) 2682 if (rc)
2688 goto err; 2683 goto err;
2689 2684
2690out: 2685out:
@@ -2796,36 +2791,39 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2796 switch (field) { 2791 switch (field) {
2797 case AUDIT_SUBJ_USER: 2792 case AUDIT_SUBJ_USER:
2798 case AUDIT_OBJ_USER: 2793 case AUDIT_OBJ_USER:
2794 rc = -EINVAL;
2799 userdatum = hashtab_search(policydb.p_users.table, rulestr); 2795 userdatum = hashtab_search(policydb.p_users.table, rulestr);
2800 if (!userdatum) 2796 if (!userdatum)
2801 rc = -EINVAL; 2797 goto out;
2802 else 2798 tmprule->au_ctxt.user = userdatum->value;
2803 tmprule->au_ctxt.user = userdatum->value;
2804 break; 2799 break;
2805 case AUDIT_SUBJ_ROLE: 2800 case AUDIT_SUBJ_ROLE:
2806 case AUDIT_OBJ_ROLE: 2801 case AUDIT_OBJ_ROLE:
2802 rc = -EINVAL;
2807 roledatum = hashtab_search(policydb.p_roles.table, rulestr); 2803 roledatum = hashtab_search(policydb.p_roles.table, rulestr);
2808 if (!roledatum) 2804 if (!roledatum)
2809 rc = -EINVAL; 2805 goto out;
2810 else 2806 tmprule->au_ctxt.role = roledatum->value;
2811 tmprule->au_ctxt.role = roledatum->value;
2812 break; 2807 break;
2813 case AUDIT_SUBJ_TYPE: 2808 case AUDIT_SUBJ_TYPE:
2814 case AUDIT_OBJ_TYPE: 2809 case AUDIT_OBJ_TYPE:
2810 rc = -EINVAL;
2815 typedatum = hashtab_search(policydb.p_types.table, rulestr); 2811 typedatum = hashtab_search(policydb.p_types.table, rulestr);
2816 if (!typedatum) 2812 if (!typedatum)
2817 rc = -EINVAL; 2813 goto out;
2818 else 2814 tmprule->au_ctxt.type = typedatum->value;
2819 tmprule->au_ctxt.type = typedatum->value;
2820 break; 2815 break;
2821 case AUDIT_SUBJ_SEN: 2816 case AUDIT_SUBJ_SEN:
2822 case AUDIT_SUBJ_CLR: 2817 case AUDIT_SUBJ_CLR:
2823 case AUDIT_OBJ_LEV_LOW: 2818 case AUDIT_OBJ_LEV_LOW:
2824 case AUDIT_OBJ_LEV_HIGH: 2819 case AUDIT_OBJ_LEV_HIGH:
2825 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); 2820 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
2821 if (rc)
2822 goto out;
2826 break; 2823 break;
2827 } 2824 }
2828 2825 rc = 0;
2826out:
2829 read_unlock(&policy_rwlock); 2827 read_unlock(&policy_rwlock);
2830 2828
2831 if (rc) { 2829 if (rc) {
@@ -3050,7 +3048,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
3050int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, 3048int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3051 u32 *sid) 3049 u32 *sid)
3052{ 3050{
3053 int rc = -EIDRM; 3051 int rc;
3054 struct context *ctx; 3052 struct context *ctx;
3055 struct context ctx_new; 3053 struct context ctx_new;
3056 3054
@@ -3061,16 +3059,15 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3061 3059
3062 read_lock(&policy_rwlock); 3060 read_lock(&policy_rwlock);
3063 3061
3064 if (secattr->flags & NETLBL_SECATTR_CACHE) { 3062 if (secattr->flags & NETLBL_SECATTR_CACHE)
3065 *sid = *(u32 *)secattr->cache->data; 3063 *sid = *(u32 *)secattr->cache->data;
3066 rc = 0; 3064 else if (secattr->flags & NETLBL_SECATTR_SECID)
3067 } else if (secattr->flags & NETLBL_SECATTR_SECID) {
3068 *sid = secattr->attr.secid; 3065 *sid = secattr->attr.secid;
3069 rc = 0; 3066 else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
3070 } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { 3067 rc = -EIDRM;
3071 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); 3068 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG);
3072 if (ctx == NULL) 3069 if (ctx == NULL)
3073 goto netlbl_secattr_to_sid_return; 3070 goto out;
3074 3071
3075 context_init(&ctx_new); 3072 context_init(&ctx_new);
3076 ctx_new.user = ctx->user; 3073 ctx_new.user = ctx->user;
@@ -3078,34 +3075,35 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3078 ctx_new.type = ctx->type; 3075 ctx_new.type = ctx->type;
3079 mls_import_netlbl_lvl(&ctx_new, secattr); 3076 mls_import_netlbl_lvl(&ctx_new, secattr);
3080 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 3077 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
3081 if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, 3078 rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat,
3082 secattr->attr.mls.cat) != 0) 3079 secattr->attr.mls.cat);
3083 goto netlbl_secattr_to_sid_return; 3080 if (rc)
3081 goto out;
3084 memcpy(&ctx_new.range.level[1].cat, 3082 memcpy(&ctx_new.range.level[1].cat,
3085 &ctx_new.range.level[0].cat, 3083 &ctx_new.range.level[0].cat,
3086 sizeof(ctx_new.range.level[0].cat)); 3084 sizeof(ctx_new.range.level[0].cat));
3087 } 3085 }
3088 if (mls_context_isvalid(&policydb, &ctx_new) != 1) 3086 rc = -EIDRM;
3089 goto netlbl_secattr_to_sid_return_cleanup; 3087 if (!mls_context_isvalid(&policydb, &ctx_new))
3088 goto out_free;
3090 3089
3091 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); 3090 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
3092 if (rc != 0) 3091 if (rc)
3093 goto netlbl_secattr_to_sid_return_cleanup; 3092 goto out_free;
3094 3093
3095 security_netlbl_cache_add(secattr, *sid); 3094 security_netlbl_cache_add(secattr, *sid);
3096 3095
3097 ebitmap_destroy(&ctx_new.range.level[0].cat); 3096 ebitmap_destroy(&ctx_new.range.level[0].cat);
3098 } else { 3097 } else
3099 *sid = SECSID_NULL; 3098 *sid = SECSID_NULL;
3100 rc = 0;
3101 }
3102 3099
3103netlbl_secattr_to_sid_return:
3104 read_unlock(&policy_rwlock); 3100 read_unlock(&policy_rwlock);
3105 return rc; 3101 return 0;
3106netlbl_secattr_to_sid_return_cleanup: 3102out_free:
3107 ebitmap_destroy(&ctx_new.range.level[0].cat); 3103 ebitmap_destroy(&ctx_new.range.level[0].cat);
3108 goto netlbl_secattr_to_sid_return; 3104out:
3105 read_unlock(&policy_rwlock);
3106 return rc;
3109} 3107}
3110 3108
3111/** 3109/**
@@ -3127,28 +3125,23 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
3127 return 0; 3125 return 0;
3128 3126
3129 read_lock(&policy_rwlock); 3127 read_lock(&policy_rwlock);
3128
3129 rc = -ENOENT;
3130 ctx = sidtab_search(&sidtab, sid); 3130 ctx = sidtab_search(&sidtab, sid);
3131 if (ctx == NULL) { 3131 if (ctx == NULL)
3132 rc = -ENOENT; 3132 goto out;
3133 goto netlbl_sid_to_secattr_failure; 3133
3134 } 3134 rc = -ENOMEM;
3135 secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], 3135 secattr->domain = kstrdup(sym_name(&policydb, SYM_TYPES, ctx->type - 1),
3136 GFP_ATOMIC); 3136 GFP_ATOMIC);
3137 if (secattr->domain == NULL) { 3137 if (secattr->domain == NULL)
3138 rc = -ENOMEM; 3138 goto out;
3139 goto netlbl_sid_to_secattr_failure; 3139
3140 }
3141 secattr->attr.secid = sid; 3140 secattr->attr.secid = sid;
3142 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; 3141 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
3143 mls_export_netlbl_lvl(ctx, secattr); 3142 mls_export_netlbl_lvl(ctx, secattr);
3144 rc = mls_export_netlbl_cat(ctx, secattr); 3143 rc = mls_export_netlbl_cat(ctx, secattr);
3145 if (rc != 0) 3144out:
3146 goto netlbl_sid_to_secattr_failure;
3147 read_unlock(&policy_rwlock);
3148
3149 return 0;
3150
3151netlbl_sid_to_secattr_failure:
3152 read_unlock(&policy_rwlock); 3145 read_unlock(&policy_rwlock);
3153 return rc; 3146 return rc;
3154} 3147}
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index e817989764cd..5840a35155fc 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -147,6 +147,17 @@ out:
147 return rc; 147 return rc;
148} 148}
149 149
150static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc)
151{
152 BUG_ON(loc >= SIDTAB_CACHE_LEN);
153
154 while (loc > 0) {
155 s->cache[loc] = s->cache[loc - 1];
156 loc--;
157 }
158 s->cache[0] = n;
159}
160
150static inline u32 sidtab_search_context(struct sidtab *s, 161static inline u32 sidtab_search_context(struct sidtab *s,
151 struct context *context) 162 struct context *context)
152{ 163{
@@ -156,14 +167,33 @@ static inline u32 sidtab_search_context(struct sidtab *s,
156 for (i = 0; i < SIDTAB_SIZE; i++) { 167 for (i = 0; i < SIDTAB_SIZE; i++) {
157 cur = s->htable[i]; 168 cur = s->htable[i];
158 while (cur) { 169 while (cur) {
159 if (context_cmp(&cur->context, context)) 170 if (context_cmp(&cur->context, context)) {
171 sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1);
160 return cur->sid; 172 return cur->sid;
173 }
161 cur = cur->next; 174 cur = cur->next;
162 } 175 }
163 } 176 }
164 return 0; 177 return 0;
165} 178}
166 179
180static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context)
181{
182 int i;
183 struct sidtab_node *node;
184
185 for (i = 0; i < SIDTAB_CACHE_LEN; i++) {
186 node = s->cache[i];
187 if (unlikely(!node))
188 return 0;
189 if (context_cmp(&node->context, context)) {
190 sidtab_update_cache(s, node, i);
191 return node->sid;
192 }
193 }
194 return 0;
195}
196
167int sidtab_context_to_sid(struct sidtab *s, 197int sidtab_context_to_sid(struct sidtab *s,
168 struct context *context, 198 struct context *context,
169 u32 *out_sid) 199 u32 *out_sid)
@@ -174,7 +204,9 @@ int sidtab_context_to_sid(struct sidtab *s,
174 204
175 *out_sid = SECSID_NULL; 205 *out_sid = SECSID_NULL;
176 206
177 sid = sidtab_search_context(s, context); 207 sid = sidtab_search_cache(s, context);
208 if (!sid)
209 sid = sidtab_search_context(s, context);
178 if (!sid) { 210 if (!sid) {
179 spin_lock_irqsave(&s->lock, flags); 211 spin_lock_irqsave(&s->lock, flags);
180 /* Rescan now that we hold the lock. */ 212 /* Rescan now that we hold the lock. */
@@ -259,12 +291,15 @@ void sidtab_destroy(struct sidtab *s)
259void sidtab_set(struct sidtab *dst, struct sidtab *src) 291void sidtab_set(struct sidtab *dst, struct sidtab *src)
260{ 292{
261 unsigned long flags; 293 unsigned long flags;
294 int i;
262 295
263 spin_lock_irqsave(&src->lock, flags); 296 spin_lock_irqsave(&src->lock, flags);
264 dst->htable = src->htable; 297 dst->htable = src->htable;
265 dst->nel = src->nel; 298 dst->nel = src->nel;
266 dst->next_sid = src->next_sid; 299 dst->next_sid = src->next_sid;
267 dst->shutdown = 0; 300 dst->shutdown = 0;
301 for (i = 0; i < SIDTAB_CACHE_LEN; i++)
302 dst->cache[i] = NULL;
268 spin_unlock_irqrestore(&src->lock, flags); 303 spin_unlock_irqrestore(&src->lock, flags);
269} 304}
270 305
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
index 64ea5b1cdea4..84dc154d9389 100644
--- a/security/selinux/ss/sidtab.h
+++ b/security/selinux/ss/sidtab.h
@@ -26,6 +26,8 @@ struct sidtab {
26 unsigned int nel; /* number of elements */ 26 unsigned int nel; /* number of elements */
27 unsigned int next_sid; /* next SID to allocate */ 27 unsigned int next_sid; /* next SID to allocate */
28 unsigned char shutdown; 28 unsigned char shutdown;
29#define SIDTAB_CACHE_LEN 3
30 struct sidtab_node *cache[SIDTAB_CACHE_LEN];
29 spinlock_t lock; 31 spinlock_t lock;
30}; 32};
31 33