diff options
Diffstat (limited to 'security/selinux/ss')
-rw-r--r-- | security/selinux/ss/hashtab.c | 1 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 4 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 176 |
3 files changed, 92 insertions, 89 deletions
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index b8f6b3e0a921..727c3b484bd3 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -8,6 +8,7 @@ #include <linux/slab.h> #include <linux/errno.h> #include "hashtab.h" +#include "security.h" static struct kmem_cache *hashtab_node_cachep __ro_after_init; diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index d338962fb0c4..3f5fd124342c 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -553,6 +553,7 @@ int mls_compute_sid(struct policydb *p, #ifdef CONFIG_NETLABEL /** * mls_export_netlbl_lvl - Export the MLS sensitivity levels to NetLabel + * @p: the policy * @context: the security context * @secattr: the NetLabel security attributes * @@ -574,6 +575,7 @@ void mls_export_netlbl_lvl(struct policydb *p, /** * mls_import_netlbl_lvl - Import the NetLabel MLS sensitivity levels + * @p: the policy * @context: the security context * @secattr: the NetLabel security attributes * @@ -595,6 +597,7 @@ void mls_import_netlbl_lvl(struct policydb *p, /** * mls_export_netlbl_cat - Export the MLS categories to NetLabel + * @p: the policy * @context: the security context * @secattr: the NetLabel security attributes * @@ -622,6 +625,7 @@ int mls_export_netlbl_cat(struct policydb *p, /** * mls_import_netlbl_cat - Import the MLS categories from NetLabel + * @p: the policy * @context: the security context * @secattr: the NetLabel security attributes * diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index e5f1b2757a83..8e92af7dd284 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1102,7 +1102,7 @@ allow: * @state: SELinux state * @ssid: source security identifier * @tsid: target security identifier - * @tclass: target security class + * @orig_tclass: target security class * @avd: access vector decisions * @xperms: extended permissions * @@ -1626,6 +1626,7 @@ int security_context_str_to_sid(struct selinux_state *state, * @scontext_len: length in bytes * @sid: security identifier, SID * @def_sid: default SID to assign on error + * @gfp_flags: the allocator get-free-page (GFP) flags * * Obtains a SID associated with the security context that * has the string representation specified by @scontext. @@ -1919,6 +1920,7 @@ out: * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class + * @qstr: object name * @out_sid: security identifier for new subject/object * * Compute a SID to use for labeling a new subject or object in the @@ -1947,6 +1949,7 @@ int security_transition_sid_user(struct selinux_state *state, /** * security_member_sid - Compute the SID for member selection. + * @state: SELinux state * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class @@ -2273,6 +2276,7 @@ void selinux_policy_commit(struct selinux_state *state, * @state: SELinux state * @data: binary policy data * @len: length of data in bytes + * @load_state: policy load state * * Load a new set of security policy configuration data, * validate it and convert the SID table as necessary. @@ -2377,6 +2381,43 @@ err_policy: } /** + * ocontext_to_sid - Helper to safely get sid for an ocontext + * @sidtab: SID table + * @c: ocontext structure + * @index: index of the context entry (0 or 1) + * @out_sid: pointer to the resulting SID value + * + * For all ocontexts except OCON_ISID the SID fields are populated + * on-demand when needed. Since updating the SID value is an SMP-sensitive + * operation, this helper must be used to do that safely. + * + * WARNING: This function may return -ESTALE, indicating that the caller + * must retry the operation after re-acquiring the policy pointer! + */ +static int ocontext_to_sid(struct sidtab *sidtab, struct ocontext *c, + size_t index, u32 *out_sid) +{ + int rc; + u32 sid; + + /* Ensure the associated sidtab entry is visible to this thread. */ + sid = smp_load_acquire(&c->sid[index]); + if (!sid) { + rc = sidtab_context_to_sid(sidtab, &c->context[index], &sid); + if (rc) + return rc; + + /* + * Ensure the new sidtab entry is visible to other threads + * when they see the SID. + */ + smp_store_release(&c->sid[index], sid); + } + *out_sid = sid; + return 0; +} + +/** * security_port_sid - Obtain the SID for a port. * @state: SELinux state * @protocol: protocol number @@ -2414,17 +2455,13 @@ retry: } if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else { *out_sid = SECINITSID_PORT; } @@ -2473,18 +2510,13 @@ retry: } if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, - &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else *out_sid = SECINITSID_UNLABELED; @@ -2497,7 +2529,7 @@ out: * security_ib_endport_sid - Obtain the SID for a subnet management interface. * @state: SELinux state * @dev_name: device name - * @port: port number + * @port_num: port number * @out_sid: security identifier */ int security_ib_endport_sid(struct selinux_state *state, @@ -2533,17 +2565,13 @@ retry: } if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else *out_sid = SECINITSID_UNLABELED; @@ -2587,25 +2615,13 @@ retry: } if (c) { - if (!c->sid[0] || !c->sid[1]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; - rc = sidtab_context_to_sid(sidtab, &c->context[1], - &c->sid[1]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, if_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *if_sid = c->sid[0]; + if (rc) + goto out; } else *if_sid = SECINITSID_NETIF; @@ -2697,18 +2713,13 @@ retry: } if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, - &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else { *out_sid = SECINITSID_NODE; } @@ -2849,9 +2860,10 @@ out_unlock: /** * __security_genfs_sid - Helper to obtain a SID for a file in a filesystem + * @policy: policy * @fstype: filesystem type * @path: path from root of mount - * @sclass: file security class + * @orig_sclass: file security class * @sid: SID for path * * Obtain a SID to use for a file in a filesystem that @@ -2873,7 +2885,7 @@ static inline int __security_genfs_sid(struct selinux_policy *policy, u16 sclass; struct genfs *genfs; struct ocontext *c; - int rc, cmp = 0; + int cmp = 0; while (path[0] == '/' && path[1] == '/') path++; @@ -2887,9 +2899,8 @@ static inline int __security_genfs_sid(struct selinux_policy *policy, break; } - rc = -ENOENT; if (!genfs || cmp) - goto out; + return -ENOENT; for (c = genfs->head; c; c = c->next) { len = strlen(c->u.name); @@ -2898,20 +2909,10 @@ static inline int __security_genfs_sid(struct selinux_policy *policy, break; } - rc = -ENOENT; if (!c) - goto out; - - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], &c->sid[0]); - if (rc) - goto out; - } + return -ENOENT; - *sid = c->sid[0]; - rc = 0; -out: - return rc; + return ocontext_to_sid(sidtab, c, 0, sid); } /** @@ -2919,7 +2920,7 @@ out: * @state: SELinux state * @fstype: filesystem type * @path: path from root of mount - * @sclass: file security class + * @orig_sclass: file security class * @sid: SID for path * * Acquire policy_rwlock before calling __security_genfs_sid() and release @@ -2996,17 +2997,13 @@ retry: if (c) { sbsec->behavior = c->v.behavior; - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, &sbsec->sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - sbsec->sid = c->sid[0]; + if (rc) + goto out; } else { rc = __security_genfs_sid(policy, fstype, "/", SECCLASS_DIR, &sbsec->sid); @@ -3305,6 +3302,7 @@ out_unlock: * @nlbl_sid: NetLabel SID * @nlbl_type: NetLabel labeling protocol type * @xfrm_sid: XFRM SID + * @peer_sid: network peer sid * * Description: * Compare the @nlbl_sid and @xfrm_sid values and if the two SIDs can be |