aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/selinux/ss/services.c115
1 files changed, 55 insertions, 60 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b341b8fd8c7c..fc3dfca475d6 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2,7 +2,7 @@
2 * Implementation of the security services. 2 * Implementation of the security services.
3 * 3 *
4 * Authors : Stephen Smalley, <sds@epoch.ncsc.mil> 4 * Authors : Stephen Smalley, <sds@epoch.ncsc.mil>
5 * James Morris <jmorris@redhat.com> 5 * James Morris <jmorris@redhat.com>
6 * 6 *
7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
8 * 8 *
@@ -11,7 +11,7 @@
11 * 11 *
12 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> 12 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
13 * 13 *
14 * Added conditional policy language extensions 14 * Added conditional policy language extensions
15 * 15 *
16 * Updated: Hewlett-Packard <paul.moore@hp.com> 16 * Updated: Hewlett-Packard <paul.moore@hp.com>
17 * 17 *
@@ -27,7 +27,7 @@
27 * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC 27 * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC
28 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 28 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
29 * This program is free software; you can redistribute it and/or modify 29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License as published by 30 * it under the terms of the GNU General Public License as published by
31 * the Free Software Foundation, version 2. 31 * the Free Software Foundation, version 2.
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
@@ -82,7 +82,7 @@ static DEFINE_MUTEX(load_mutex);
82 82
83static struct sidtab sidtab; 83static struct sidtab sidtab;
84struct policydb policydb; 84struct policydb policydb;
85int ss_initialized = 0; 85int ss_initialized;
86 86
87/* 87/*
88 * The largest sequence number that has been used when 88 * The largest sequence number that has been used when
@@ -90,7 +90,7 @@ int ss_initialized = 0;
90 * The sequence number only changes when a policy change 90 * The sequence number only changes when a policy change
91 * occurs. 91 * occurs.
92 */ 92 */
93static u32 latest_granting = 0; 93static u32 latest_granting;
94 94
95/* Forward declaration. */ 95/* Forward declaration. */
96static int context_struct_to_string(struct context *context, char **scontext, 96static int context_struct_to_string(struct context *context, char **scontext,
@@ -163,10 +163,10 @@ static int constraint_expr_eval(struct context *scontext,
163 val1 - 1); 163 val1 - 1);
164 continue; 164 continue;
165 case CEXPR_INCOMP: 165 case CEXPR_INCOMP:
166 s[++sp] = ( !ebitmap_get_bit(&r1->dominates, 166 s[++sp] = (!ebitmap_get_bit(&r1->dominates,
167 val2 - 1) && 167 val2 - 1) &&
168 !ebitmap_get_bit(&r2->dominates, 168 !ebitmap_get_bit(&r2->dominates,
169 val1 - 1) ); 169 val1 - 1));
170 continue; 170 continue;
171 default: 171 default:
172 break; 172 break;
@@ -409,7 +409,7 @@ static int context_struct_compute_av(struct context *scontext,
409 } 409 }
410 if (!ra) 410 if (!ra)
411 avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | 411 avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION |
412 PROCESS__DYNTRANSITION); 412 PROCESS__DYNTRANSITION);
413 } 413 }
414 414
415 return 0; 415 return 0;
@@ -445,9 +445,9 @@ int security_permissive_sid(u32 sid)
445} 445}
446 446
447static int security_validtrans_handle_fail(struct context *ocontext, 447static int security_validtrans_handle_fail(struct context *ocontext,
448 struct context *ncontext, 448 struct context *ncontext,
449 struct context *tcontext, 449 struct context *tcontext,
450 u16 tclass) 450 u16 tclass)
451{ 451{
452 char *o = NULL, *n = NULL, *t = NULL; 452 char *o = NULL, *n = NULL, *t = NULL;
453 u32 olen, nlen, tlen; 453 u32 olen, nlen, tlen;
@@ -459,9 +459,9 @@ static int security_validtrans_handle_fail(struct context *ocontext,
459 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 459 if (context_struct_to_string(tcontext, &t, &tlen) < 0)
460 goto out; 460 goto out;
461 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 461 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
462 "security_validate_transition: denied for" 462 "security_validate_transition: denied for"
463 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", 463 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
464 o, n, t, policydb.p_class_val_to_name[tclass-1]); 464 o, n, t, policydb.p_class_val_to_name[tclass-1]);
465out: 465out:
466 kfree(o); 466 kfree(o);
467 kfree(n); 467 kfree(n);
@@ -473,7 +473,7 @@ out:
473} 473}
474 474
475int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, 475int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
476 u16 tclass) 476 u16 tclass)
477{ 477{
478 struct context *ocontext; 478 struct context *ocontext;
479 struct context *ncontext; 479 struct context *ncontext;
@@ -533,9 +533,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
533 constraint = tclass_datum->validatetrans; 533 constraint = tclass_datum->validatetrans;
534 while (constraint) { 534 while (constraint) {
535 if (!constraint_expr_eval(ocontext, ncontext, tcontext, 535 if (!constraint_expr_eval(ocontext, ncontext, tcontext,
536 constraint->expr)) { 536 constraint->expr)) {
537 rc = security_validtrans_handle_fail(ocontext, ncontext, 537 rc = security_validtrans_handle_fail(ocontext, ncontext,
538 tcontext, tclass); 538 tcontext, tclass);
539 goto out; 539 goto out;
540 } 540 }
541 constraint = constraint->next; 541 constraint = constraint->next;
@@ -623,9 +623,8 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
623 623
624 /* Allocate space for the context; caller must free this space. */ 624 /* Allocate space for the context; caller must free this space. */
625 scontextp = kmalloc(*scontext_len, GFP_ATOMIC); 625 scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
626 if (!scontextp) { 626 if (!scontextp)
627 return -ENOMEM; 627 return -ENOMEM;
628 }
629 *scontext = scontextp; 628 *scontext = scontextp;
630 629
631 /* 630 /*
@@ -636,8 +635,8 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
636 policydb.p_role_val_to_name[context->role - 1], 635 policydb.p_role_val_to_name[context->role - 1],
637 policydb.p_type_val_to_name[context->type - 1]); 636 policydb.p_type_val_to_name[context->type - 1]);
638 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + 637 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) +
639 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + 638 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) +
640 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); 639 1 + strlen(policydb.p_type_val_to_name[context->type - 1]);
641 640
642 mls_sid_to_context(context, &scontextp); 641 mls_sid_to_context(context, &scontextp);
643 642
@@ -678,7 +677,7 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
678 char *scontextp; 677 char *scontextp;
679 678
680 *scontext_len = strlen(initial_sid_to_string[sid]) + 1; 679 *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
681 scontextp = kmalloc(*scontext_len,GFP_ATOMIC); 680 scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
682 if (!scontextp) { 681 if (!scontextp) {
683 rc = -ENOMEM; 682 rc = -ENOMEM;
684 goto out; 683 goto out;
@@ -974,7 +973,7 @@ static int security_compute_sid(u32 ssid,
974 avdatum = avtab_search(&policydb.te_avtab, &avkey); 973 avdatum = avtab_search(&policydb.te_avtab, &avkey);
975 974
976 /* If no permanent rule, also check for enabled conditional rules */ 975 /* If no permanent rule, also check for enabled conditional rules */
977 if(!avdatum) { 976 if (!avdatum) {
978 node = avtab_search_node(&policydb.te_cond_avtab, &avkey); 977 node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
979 for (; node != NULL; node = avtab_search_node_next(node, specified)) { 978 for (; node != NULL; node = avtab_search_node_next(node, specified)) {
980 if (node->key.specified & AVTAB_ENABLED) { 979 if (node->key.specified & AVTAB_ENABLED) {
@@ -1288,26 +1287,23 @@ static int convert_context(u32 key,
1288 1287
1289 /* Convert the user. */ 1288 /* Convert the user. */
1290 usrdatum = hashtab_search(args->newp->p_users.table, 1289 usrdatum = hashtab_search(args->newp->p_users.table,
1291 args->oldp->p_user_val_to_name[c->user - 1]); 1290 args->oldp->p_user_val_to_name[c->user - 1]);
1292 if (!usrdatum) { 1291 if (!usrdatum)
1293 goto bad; 1292 goto bad;
1294 }
1295 c->user = usrdatum->value; 1293 c->user = usrdatum->value;
1296 1294
1297 /* Convert the role. */ 1295 /* Convert the role. */
1298 role = hashtab_search(args->newp->p_roles.table, 1296 role = hashtab_search(args->newp->p_roles.table,
1299 args->oldp->p_role_val_to_name[c->role - 1]); 1297 args->oldp->p_role_val_to_name[c->role - 1]);
1300 if (!role) { 1298 if (!role)
1301 goto bad; 1299 goto bad;
1302 }
1303 c->role = role->value; 1300 c->role = role->value;
1304 1301
1305 /* Convert the type. */ 1302 /* Convert the type. */
1306 typdatum = hashtab_search(args->newp->p_types.table, 1303 typdatum = hashtab_search(args->newp->p_types.table,
1307 args->oldp->p_type_val_to_name[c->type - 1]); 1304 args->oldp->p_type_val_to_name[c->type - 1]);
1308 if (!typdatum) { 1305 if (!typdatum)
1309 goto bad; 1306 goto bad;
1310 }
1311 c->type = typdatum->value; 1307 c->type = typdatum->value;
1312 1308
1313 rc = mls_convert_context(args->oldp, args->newp, c); 1309 rc = mls_convert_context(args->oldp, args->newp, c);
@@ -1556,8 +1552,8 @@ static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask)
1556{ 1552{
1557 int i, fail = 0; 1553 int i, fail = 0;
1558 1554
1559 for(i = 0; i < 4; i++) 1555 for (i = 0; i < 4; i++)
1560 if(addr[i] != (input[i] & mask[i])) { 1556 if (addr[i] != (input[i] & mask[i])) {
1561 fail = 1; 1557 fail = 1;
1562 break; 1558 break;
1563 } 1559 }
@@ -1656,7 +1652,7 @@ out:
1656 */ 1652 */
1657 1653
1658int security_get_user_sids(u32 fromsid, 1654int security_get_user_sids(u32 fromsid,
1659 char *username, 1655 char *username,
1660 u32 **sids, 1656 u32 **sids,
1661 u32 *nel) 1657 u32 *nel)
1662{ 1658{
@@ -1766,7 +1762,7 @@ out:
1766 * transition SIDs or task SIDs. 1762 * transition SIDs or task SIDs.
1767 */ 1763 */
1768int security_genfs_sid(const char *fstype, 1764int security_genfs_sid(const char *fstype,
1769 char *path, 1765 char *path,
1770 u16 sclass, 1766 u16 sclass,
1771 u32 *sid) 1767 u32 *sid)
1772{ 1768{
@@ -1881,7 +1877,7 @@ int security_get_bools(int *len, char ***names, int **values)
1881 goto out; 1877 goto out;
1882 } 1878 }
1883 1879
1884 *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC); 1880 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC);
1885 if (!*names) 1881 if (!*names)
1886 goto err; 1882 goto err;
1887 1883
@@ -1893,7 +1889,7 @@ int security_get_bools(int *len, char ***names, int **values)
1893 size_t name_len; 1889 size_t name_len;
1894 (*values)[i] = policydb.bool_val_to_struct[i]->state; 1890 (*values)[i] = policydb.bool_val_to_struct[i]->state;
1895 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 1891 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1;
1896 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 1892 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
1897 if (!(*names)[i]) 1893 if (!(*names)[i])
1898 goto err; 1894 goto err;
1899 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 1895 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len);
@@ -1938,11 +1934,10 @@ int security_set_bools(int len, int *values)
1938 audit_get_loginuid(current), 1934 audit_get_loginuid(current),
1939 audit_get_sessionid(current)); 1935 audit_get_sessionid(current));
1940 } 1936 }
1941 if (values[i]) { 1937 if (values[i])
1942 policydb.bool_val_to_struct[i]->state = 1; 1938 policydb.bool_val_to_struct[i]->state = 1;
1943 } else { 1939 else
1944 policydb.bool_val_to_struct[i]->state = 0; 1940 policydb.bool_val_to_struct[i]->state = 0;
1945 }
1946 } 1941 }
1947 1942
1948 for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { 1943 for (cur = policydb.cond_list; cur != NULL; cur = cur->next) {
@@ -2435,7 +2430,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2435 2430
2436 if (!rule) { 2431 if (!rule) {
2437 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2432 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2438 "selinux_audit_rule_match: missing rule\n"); 2433 "selinux_audit_rule_match: missing rule\n");
2439 return -ENOENT; 2434 return -ENOENT;
2440 } 2435 }
2441 2436
@@ -2443,7 +2438,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2443 2438
2444 if (rule->au_seqno < latest_granting) { 2439 if (rule->au_seqno < latest_granting) {
2445 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2440 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2446 "selinux_audit_rule_match: stale rule\n"); 2441 "selinux_audit_rule_match: stale rule\n");
2447 match = -ESTALE; 2442 match = -ESTALE;
2448 goto out; 2443 goto out;
2449 } 2444 }
@@ -2451,8 +2446,8 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2451 ctxt = sidtab_search(&sidtab, sid); 2446 ctxt = sidtab_search(&sidtab, sid);
2452 if (!ctxt) { 2447 if (!ctxt) {
2453 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, 2448 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2454 "selinux_audit_rule_match: unrecognized SID %d\n", 2449 "selinux_audit_rule_match: unrecognized SID %d\n",
2455 sid); 2450 sid);
2456 match = -ENOENT; 2451 match = -ENOENT;
2457 goto out; 2452 goto out;
2458 } 2453 }
@@ -2498,36 +2493,36 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
2498 case AUDIT_OBJ_LEV_LOW: 2493 case AUDIT_OBJ_LEV_LOW:
2499 case AUDIT_OBJ_LEV_HIGH: 2494 case AUDIT_OBJ_LEV_HIGH:
2500 level = ((field == AUDIT_SUBJ_SEN || 2495 level = ((field == AUDIT_SUBJ_SEN ||
2501 field == AUDIT_OBJ_LEV_LOW) ? 2496 field == AUDIT_OBJ_LEV_LOW) ?
2502 &ctxt->range.level[0] : &ctxt->range.level[1]); 2497 &ctxt->range.level[0] : &ctxt->range.level[1]);
2503 switch (op) { 2498 switch (op) {
2504 case AUDIT_EQUAL: 2499 case AUDIT_EQUAL:
2505 match = mls_level_eq(&rule->au_ctxt.range.level[0], 2500 match = mls_level_eq(&rule->au_ctxt.range.level[0],
2506 level); 2501 level);
2507 break; 2502 break;
2508 case AUDIT_NOT_EQUAL: 2503 case AUDIT_NOT_EQUAL:
2509 match = !mls_level_eq(&rule->au_ctxt.range.level[0], 2504 match = !mls_level_eq(&rule->au_ctxt.range.level[0],
2510 level); 2505 level);
2511 break; 2506 break;
2512 case AUDIT_LESS_THAN: 2507 case AUDIT_LESS_THAN:
2513 match = (mls_level_dom(&rule->au_ctxt.range.level[0], 2508 match = (mls_level_dom(&rule->au_ctxt.range.level[0],
2514 level) && 2509 level) &&
2515 !mls_level_eq(&rule->au_ctxt.range.level[0], 2510 !mls_level_eq(&rule->au_ctxt.range.level[0],
2516 level)); 2511 level));
2517 break; 2512 break;
2518 case AUDIT_LESS_THAN_OR_EQUAL: 2513 case AUDIT_LESS_THAN_OR_EQUAL:
2519 match = mls_level_dom(&rule->au_ctxt.range.level[0], 2514 match = mls_level_dom(&rule->au_ctxt.range.level[0],
2520 level); 2515 level);
2521 break; 2516 break;
2522 case AUDIT_GREATER_THAN: 2517 case AUDIT_GREATER_THAN:
2523 match = (mls_level_dom(level, 2518 match = (mls_level_dom(level,
2524 &rule->au_ctxt.range.level[0]) && 2519 &rule->au_ctxt.range.level[0]) &&
2525 !mls_level_eq(level, 2520 !mls_level_eq(level,
2526 &rule->au_ctxt.range.level[0])); 2521 &rule->au_ctxt.range.level[0]));
2527 break; 2522 break;
2528 case AUDIT_GREATER_THAN_OR_EQUAL: 2523 case AUDIT_GREATER_THAN_OR_EQUAL:
2529 match = mls_level_dom(level, 2524 match = mls_level_dom(level,
2530 &rule->au_ctxt.range.level[0]); 2525 &rule->au_ctxt.range.level[0]);
2531 break; 2526 break;
2532 } 2527 }
2533 } 2528 }
@@ -2554,7 +2549,7 @@ static int __init aurule_init(void)
2554 int err; 2549 int err;
2555 2550
2556 err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, 2551 err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET,
2557 SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); 2552 SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
2558 if (err) 2553 if (err)
2559 panic("avc_add_callback() failed, error %d\n", err); 2554 panic("avc_add_callback() failed, error %d\n", err);
2560 2555