diff options
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r-- | security/selinux/ss/services.c | 62 |
1 files changed, 56 insertions, 6 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 2abbc49914e6..4e976f58b980 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -26,6 +26,10 @@ | |||
26 | * | 26 | * |
27 | * Added support for bounds domain and audit messaged on masked permissions | 27 | * Added support for bounds domain and audit messaged on masked permissions |
28 | * | 28 | * |
29 | * Updated: Guido Trentalancia <guido@trentalancia.com> | ||
30 | * | ||
31 | * Added support for runtime switching of the policy type | ||
32 | * | ||
29 | * Copyright (C) 2008, 2009 NEC Corporation | 33 | * Copyright (C) 2008, 2009 NEC Corporation |
30 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. | 34 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. |
31 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. | 35 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
@@ -232,6 +236,10 @@ static void map_decision(u16 tclass, struct av_decision *avd, | |||
232 | } | 236 | } |
233 | } | 237 | } |
234 | 238 | ||
239 | int security_mls_enabled(void) | ||
240 | { | ||
241 | return policydb.mls_enabled; | ||
242 | } | ||
235 | 243 | ||
236 | /* | 244 | /* |
237 | * Return the boolean value of a constraint expression | 245 | * Return the boolean value of a constraint expression |
@@ -1550,6 +1558,8 @@ static int convert_context(u32 key, | |||
1550 | { | 1558 | { |
1551 | struct convert_context_args *args; | 1559 | struct convert_context_args *args; |
1552 | struct context oldc; | 1560 | struct context oldc; |
1561 | struct ocontext *oc; | ||
1562 | struct mls_range *range; | ||
1553 | struct role_datum *role; | 1563 | struct role_datum *role; |
1554 | struct type_datum *typdatum; | 1564 | struct type_datum *typdatum; |
1555 | struct user_datum *usrdatum; | 1565 | struct user_datum *usrdatum; |
@@ -1620,9 +1630,39 @@ static int convert_context(u32 key, | |||
1620 | goto bad; | 1630 | goto bad; |
1621 | c->type = typdatum->value; | 1631 | c->type = typdatum->value; |
1622 | 1632 | ||
1623 | rc = mls_convert_context(args->oldp, args->newp, c); | 1633 | /* Convert the MLS fields if dealing with MLS policies */ |
1624 | if (rc) | 1634 | if (args->oldp->mls_enabled && args->newp->mls_enabled) { |
1625 | goto bad; | 1635 | rc = mls_convert_context(args->oldp, args->newp, c); |
1636 | if (rc) | ||
1637 | goto bad; | ||
1638 | } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) { | ||
1639 | /* | ||
1640 | * Switching between MLS and non-MLS policy: | ||
1641 | * free any storage used by the MLS fields in the | ||
1642 | * context for all existing entries in the sidtab. | ||
1643 | */ | ||
1644 | mls_context_destroy(c); | ||
1645 | } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) { | ||
1646 | /* | ||
1647 | * Switching between non-MLS and MLS policy: | ||
1648 | * ensure that the MLS fields of the context for all | ||
1649 | * existing entries in the sidtab are filled in with a | ||
1650 | * suitable default value, likely taken from one of the | ||
1651 | * initial SIDs. | ||
1652 | */ | ||
1653 | oc = args->newp->ocontexts[OCON_ISID]; | ||
1654 | while (oc && oc->sid[0] != SECINITSID_UNLABELED) | ||
1655 | oc = oc->next; | ||
1656 | if (!oc) { | ||
1657 | printk(KERN_ERR "SELinux: unable to look up" | ||
1658 | " the initial SIDs list\n"); | ||
1659 | goto bad; | ||
1660 | } | ||
1661 | range = &oc->context[0].range; | ||
1662 | rc = mls_range_set(c, range); | ||
1663 | if (rc) | ||
1664 | goto bad; | ||
1665 | } | ||
1626 | 1666 | ||
1627 | /* Check the validity of the new context. */ | 1667 | /* Check the validity of the new context. */ |
1628 | if (!policydb_context_isvalid(args->newp, c)) { | 1668 | if (!policydb_context_isvalid(args->newp, c)) { |
@@ -1718,6 +1758,12 @@ int security_load_policy(void *data, size_t len) | |||
1718 | if (policydb_read(&newpolicydb, fp)) | 1758 | if (policydb_read(&newpolicydb, fp)) |
1719 | return -EINVAL; | 1759 | return -EINVAL; |
1720 | 1760 | ||
1761 | /* If switching between different policy types, log MLS status */ | ||
1762 | if (policydb.mls_enabled && !newpolicydb.mls_enabled) | ||
1763 | printk(KERN_INFO "SELinux: Disabling MLS support...\n"); | ||
1764 | else if (!policydb.mls_enabled && newpolicydb.mls_enabled) | ||
1765 | printk(KERN_INFO "SELinux: Enabling MLS support...\n"); | ||
1766 | |||
1721 | rc = policydb_load_isids(&newpolicydb, &newsidtab); | 1767 | rc = policydb_load_isids(&newpolicydb, &newsidtab); |
1722 | if (rc) { | 1768 | if (rc) { |
1723 | printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); | 1769 | printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); |
@@ -1749,8 +1795,12 @@ int security_load_policy(void *data, size_t len) | |||
1749 | args.oldp = &policydb; | 1795 | args.oldp = &policydb; |
1750 | args.newp = &newpolicydb; | 1796 | args.newp = &newpolicydb; |
1751 | rc = sidtab_map(&newsidtab, convert_context, &args); | 1797 | rc = sidtab_map(&newsidtab, convert_context, &args); |
1752 | if (rc) | 1798 | if (rc) { |
1799 | printk(KERN_ERR "SELinux: unable to convert the internal" | ||
1800 | " representation of contexts in the new SID" | ||
1801 | " table\n"); | ||
1753 | goto err; | 1802 | goto err; |
1803 | } | ||
1754 | 1804 | ||
1755 | /* Save the old policydb and SID table to free later. */ | 1805 | /* Save the old policydb and SID table to free later. */ |
1756 | memcpy(&oldpolicydb, &policydb, sizeof policydb); | 1806 | memcpy(&oldpolicydb, &policydb, sizeof policydb); |
@@ -2346,7 +2396,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2346 | u32 len; | 2396 | u32 len; |
2347 | int rc = 0; | 2397 | int rc = 0; |
2348 | 2398 | ||
2349 | if (!ss_initialized || !selinux_mls_enabled) { | 2399 | if (!ss_initialized || !policydb.mls_enabled) { |
2350 | *new_sid = sid; | 2400 | *new_sid = sid; |
2351 | goto out; | 2401 | goto out; |
2352 | } | 2402 | } |
@@ -2447,7 +2497,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, | |||
2447 | /* we don't need to check ss_initialized here since the only way both | 2497 | /* we don't need to check ss_initialized here since the only way both |
2448 | * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the | 2498 | * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the |
2449 | * security server was initialized and ss_initialized was true */ | 2499 | * security server was initialized and ss_initialized was true */ |
2450 | if (!selinux_mls_enabled) { | 2500 | if (!policydb.mls_enabled) { |
2451 | *peer_sid = SECSID_NULL; | 2501 | *peer_sid = SECSID_NULL; |
2452 | return 0; | 2502 | return 0; |
2453 | } | 2503 | } |