aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/policydb.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r--security/selinux/ss/policydb.c109
1 files changed, 82 insertions, 27 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index af41fdfe1a7..5adca670e5a 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -254,12 +254,17 @@ static int common_index(void *key, void *datum, void *datap)
254{ 254{
255 struct policydb *p; 255 struct policydb *p;
256 struct common_datum *comdatum; 256 struct common_datum *comdatum;
257 struct flex_array *fa;
257 258
258 comdatum = datum; 259 comdatum = datum;
259 p = datap; 260 p = datap;
260 if (!comdatum->value || comdatum->value > p->p_commons.nprim) 261 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
261 return -EINVAL; 262 return -EINVAL;
262 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();
263 return 0; 268 return 0;
264} 269}
265 270
@@ -267,12 +272,16 @@ static int class_index(void *key, void *datum, void *datap)
267{ 272{
268 struct policydb *p; 273 struct policydb *p;
269 struct class_datum *cladatum; 274 struct class_datum *cladatum;
275 struct flex_array *fa;
270 276
271 cladatum = datum; 277 cladatum = datum;
272 p = datap; 278 p = datap;
273 if (!cladatum->value || cladatum->value > p->p_classes.nprim) 279 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
274 return -EINVAL; 280 return -EINVAL;
275 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();
276 p->class_val_to_struct[cladatum->value - 1] = cladatum; 285 p->class_val_to_struct[cladatum->value - 1] = cladatum;
277 return 0; 286 return 0;
278} 287}
@@ -281,6 +290,7 @@ static int role_index(void *key, void *datum, void *datap)
281{ 290{
282 struct policydb *p; 291 struct policydb *p;
283 struct role_datum *role; 292 struct role_datum *role;
293 struct flex_array *fa;
284 294
285 role = datum; 295 role = datum;
286 p = datap; 296 p = datap;
@@ -288,7 +298,11 @@ static int role_index(void *key, void *datum, void *datap)
288 || role->value > p->p_roles.nprim 298 || role->value > p->p_roles.nprim
289 || role->bounds > p->p_roles.nprim) 299 || role->bounds > p->p_roles.nprim)
290 return -EINVAL; 300 return -EINVAL;
291 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();
292 p->role_val_to_struct[role->value - 1] = role; 306 p->role_val_to_struct[role->value - 1] = role;
293 return 0; 307 return 0;
294} 308}
@@ -297,6 +311,7 @@ static int type_index(void *key, void *datum, void *datap)
297{ 311{
298 struct policydb *p; 312 struct policydb *p;
299 struct type_datum *typdatum; 313 struct type_datum *typdatum;
314 struct flex_array *fa;
300 315
301 typdatum = datum; 316 typdatum = datum;
302 p = datap; 317 p = datap;
@@ -306,10 +321,13 @@ static int type_index(void *key, void *datum, void *datap)
306 || typdatum->value > p->p_types.nprim 321 || typdatum->value > p->p_types.nprim
307 || typdatum->bounds > p->p_types.nprim) 322 || typdatum->bounds > p->p_types.nprim)
308 return -EINVAL; 323 return -EINVAL;
309 p->p_type_val_to_name[typdatum->value - 1] = key; 324 fa = p->sym_val_to_name[SYM_TYPES];
310 /* this flex array was all preallocated, this cannot fail */ 325 if (flex_array_put_ptr(fa, typdatum->value - 1, key,
311 if (flex_array_put_ptr(p->type_val_to_struct_array, 326 GFP_KERNEL | __GFP_ZERO))
312 typdatum->value - 1, typdatum, 327 BUG();
328
329 fa = p->type_val_to_struct_array;
330 if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
313 GFP_KERNEL | __GFP_ZERO)) 331 GFP_KERNEL | __GFP_ZERO))
314 BUG(); 332 BUG();
315 } 333 }
@@ -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;
@@ -392,9 +423,16 @@ static int policydb_index_classes(struct policydb *p)
392 int rc; 423 int rc;
393 424
394 rc = -ENOMEM; 425 rc = -ENOMEM;
395 p->p_common_val_to_name = 426 p->sym_val_to_name[SYM_COMMONS] = flex_array_alloc(sizeof(char *),
396 kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL); 427 p->p_commons.nprim,
397 if (!p->p_common_val_to_name) 428 GFP_KERNEL | __GFP_ZERO);
429 if (!p->sym_val_to_name[SYM_COMMONS])
430 goto out;
431
432 rc = flex_array_prealloc(p->sym_val_to_name[SYM_COMMONS],
433 0, p->p_commons.nprim - 1,
434 GFP_KERNEL | __GFP_ZERO);
435 if (rc)
398 goto out; 436 goto out;
399 437
400 rc = hashtab_map(p->p_commons.table, common_index, p); 438 rc = hashtab_map(p->p_commons.table, common_index, p);
@@ -408,9 +446,16 @@ static int policydb_index_classes(struct policydb *p)
408 goto out; 446 goto out;
409 447
410 rc = -ENOMEM; 448 rc = -ENOMEM;
411 p->p_class_val_to_name = 449 p->sym_val_to_name[SYM_CLASSES] = flex_array_alloc(sizeof(char *),
412 kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL); 450 p->p_classes.nprim,
413 if (!p->p_class_val_to_name) 451 GFP_KERNEL | __GFP_ZERO);
452 if (!p->sym_val_to_name[SYM_CLASSES])
453 goto out;
454
455 rc = flex_array_prealloc(p->sym_val_to_name[SYM_CLASSES],
456 0, p->p_classes.nprim - 1,
457 GFP_KERNEL | __GFP_ZERO);
458 if (rc)
414 goto out; 459 goto out;
415 460
416 rc = hashtab_map(p->p_classes.table, class_index, p); 461 rc = hashtab_map(p->p_classes.table, class_index, p);
@@ -507,10 +552,18 @@ static int policydb_index_others(struct policydb *p)
507 552
508 for (i = SYM_ROLES; i < SYM_NUM; i++) { 553 for (i = SYM_ROLES; i < SYM_NUM; i++) {
509 rc = -ENOMEM; 554 rc = -ENOMEM;
510 p->sym_val_to_name[i] = 555 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
511 kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); 556 p->symtab[i].nprim,
557 GFP_KERNEL | __GFP_ZERO);
512 if (!p->sym_val_to_name[i]) 558 if (!p->sym_val_to_name[i])
513 goto out; 559 goto out;
560
561 rc = flex_array_prealloc(p->sym_val_to_name[i],
562 0, p->symtab[i].nprim - 1,
563 GFP_KERNEL | __GFP_ZERO);
564 if (rc)
565 goto out;
566
514 rc = hashtab_map(p->symtab[i].table, index_f[i], p); 567 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
515 if (rc) 568 if (rc)
516 goto out; 569 goto out;
@@ -703,8 +756,10 @@ void policydb_destroy(struct policydb *p)
703 hashtab_destroy(p->symtab[i].table); 756 hashtab_destroy(p->symtab[i].table);
704 } 757 }
705 758
706 for (i = 0; i < SYM_NUM; i++) 759 for (i = 0; i < SYM_NUM; i++) {
707 kfree(p->sym_val_to_name[i]); 760 if (p->sym_val_to_name[i])
761 flex_array_free(p->sym_val_to_name[i]);
762 }
708 763
709 kfree(p->class_val_to_struct); 764 kfree(p->class_val_to_struct);
710 kfree(p->role_val_to_struct); 765 kfree(p->role_val_to_struct);
@@ -1566,9 +1621,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap)
1566 printk(KERN_ERR 1621 printk(KERN_ERR
1567 "SELinux: boundary violated policy: " 1622 "SELinux: boundary violated policy: "
1568 "user=%s role=%s bounds=%s\n", 1623 "user=%s role=%s bounds=%s\n",
1569 p->p_user_val_to_name[user->value - 1], 1624 sym_name(p, SYM_USERS, user->value - 1),
1570 p->p_role_val_to_name[bit], 1625 sym_name(p, SYM_ROLES, bit),
1571 p->p_user_val_to_name[upper->value - 1]); 1626 sym_name(p, SYM_USERS, upper->value - 1));
1572 1627
1573 return -EINVAL; 1628 return -EINVAL;
1574 } 1629 }
@@ -1603,9 +1658,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1603 printk(KERN_ERR 1658 printk(KERN_ERR
1604 "SELinux: boundary violated policy: " 1659 "SELinux: boundary violated policy: "
1605 "role=%s type=%s bounds=%s\n", 1660 "role=%s type=%s bounds=%s\n",
1606 p->p_role_val_to_name[role->value - 1], 1661 sym_name(p, SYM_ROLES, role->value - 1),
1607 p->p_type_val_to_name[bit], 1662 sym_name(p, SYM_TYPES, bit),
1608 p->p_role_val_to_name[upper->value - 1]); 1663 sym_name(p, SYM_ROLES, upper->value - 1));
1609 1664
1610 return -EINVAL; 1665 return -EINVAL;
1611 } 1666 }
@@ -1637,7 +1692,7 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1637 printk(KERN_ERR "SELinux: type %s: " 1692 printk(KERN_ERR "SELinux: type %s: "
1638 "bounded by attribute %s", 1693 "bounded by attribute %s",
1639 (char *) key, 1694 (char *) key,
1640 p->p_type_val_to_name[upper->value - 1]); 1695 sym_name(p, SYM_TYPES, upper->value - 1));
1641 return -EINVAL; 1696 return -EINVAL;
1642 } 1697 }
1643 } 1698 }