diff options
-rw-r--r-- | security/selinux/hooks.c | 3 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 71 | ||||
-rw-r--r-- | security/selinux/ss/mls.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 55 |
5 files changed, 97 insertions, 38 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6be27385114..10fd51c9056 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -826,7 +826,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent sid = sbsec->def_sid; rc = 0; } else { - rc = security_context_to_sid(context, rc, &sid); + rc = security_context_to_sid_default(context, rc, &sid, + sbsec->def_sid); if (rc) { printk(KERN_WARNING "%s: context_to_sid(%s) " "returned %d for dev=%s ino=%ld\n", diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index fa187c9a351..71c0a19c975 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -65,6 +65,8 @@ int security_sid_to_context(u32 sid, char **scontext, int security_context_to_sid(char *scontext, u32 scontext_len, u32 *out_sid); +int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid); + int security_get_user_sids(u32 callsid, char *username, u32 **sids, u32 *nel); diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 756036bcc24..d4c32c39ccc 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/errno.h> +#include "sidtab.h" #include "mls.h" #include "policydb.h" #include "services.h" @@ -208,6 +209,26 @@ int mls_context_isvalid(struct policydb *p, struct context *c) } /* + * Copies the MLS range from `src' into `dst'. + */ +static inline int mls_copy_context(struct context *dst, + struct context *src) +{ + int l, rc = 0; + + /* Copy the MLS range from the source context */ + for (l = 0; l < 2; l++) { + dst->range.level[l].sens = src->range.level[l].sens; + rc = ebitmap_cpy(&dst->range.level[l].cat, + &src->range.level[l].cat); + if (rc) + break; + } + + return rc; +} + +/* * Set the MLS fields in the security context structure * `context' based on the string representation in * the string `*scontext'. Update `*scontext' to @@ -216,10 +237,20 @@ int mls_context_isvalid(struct policydb *p, struct context *c) * * This function modifies the string in place, inserting * NULL characters to terminate the MLS fields. + * + * If a def_sid is provided and no MLS field is present, + * copy the MLS field of the associated default context. + * Used for upgraded to MLS systems where objects may lack + * MLS fields. + * + * Policy read-lock must be held for sidtab lookup. + * */ int mls_context_to_sid(char oldc, char **scontext, - struct context *context) + struct context *context, + struct sidtab *s, + u32 def_sid) { char delim; @@ -231,9 +262,23 @@ int mls_context_to_sid(char oldc, if (!selinux_mls_enabled) return 0; - /* No MLS component to the security context. */ - if (!oldc) + /* + * No MLS component to the security context, try and map to + * default if provided. + */ + if (!oldc) { + struct context *defcon; + + if (def_sid == SECSID_NULL) + goto out; + + defcon = sidtab_search(s, def_sid); + if (!defcon) + goto out; + + rc = mls_copy_context(context, defcon); goto out; + } /* Extract low sensitivity. */ scontextp = p = *scontext; @@ -334,26 +379,6 @@ out: } /* - * Copies the MLS range from `src' into `dst'. - */ -static inline int mls_copy_context(struct context *dst, - struct context *src) -{ - int l, rc = 0; - - /* Copy the MLS range from the source context */ - for (l = 0; l < 2; l++) { - dst->range.level[l].sens = src->range.level[l].sens; - rc = ebitmap_cpy(&dst->range.level[l].cat, - &src->range.level[l].cat); - if (rc) - break; - } - - return rc; -} - -/* * Copies the effective MLS range from `src' into `dst'. */ static inline int mls_scopy_context(struct context *dst, diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 0d37beaa85e..03de697c805 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -23,7 +23,9 @@ int mls_context_isvalid(struct policydb *p, struct context *c); int mls_context_to_sid(char oldc, char **scontext, - struct context *context); + struct context *context, + struct sidtab *s, + u32 def_sid); int mls_convert_context(struct policydb *oldp, struct policydb *newp, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 922bb45054a..014120474e6 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -601,18 +601,7 @@ out: } -/** - * security_context_to_sid - Obtain a SID for a given security context. - * @scontext: security context - * @scontext_len: length in bytes - * @sid: security identifier, SID - * - * Obtains a SID associated with the security context that - * has the string representation specified by @scontext. - * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient - * memory is available, or 0 on success. - */ -int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) +static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) { char *scontext2; struct context context; @@ -703,7 +692,7 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) context.type = typdatum->value; - rc = mls_context_to_sid(oldc, &p, &context); + rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); if (rc) goto out_unlock; @@ -727,6 +716,46 @@ out: return rc; } +/** + * security_context_to_sid - Obtain a SID for a given security context. + * @scontext: security context + * @scontext_len: length in bytes + * @sid: security identifier, SID + * + * Obtains a SID associated with the security context that + * has the string representation specified by @scontext. + * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient + * memory is available, or 0 on success. + */ +int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) +{ + return security_context_to_sid_core(scontext, scontext_len, + sid, SECSID_NULL); +} + +/** + * security_context_to_sid_default - Obtain a SID for a given security context, + * falling back to specified default if needed. + * + * @scontext: security context + * @scontext_len: length in bytes + * @sid: security identifier, SID + * @def_sid: default SID to assign on errror + * + * Obtains a SID associated with the security context that + * has the string representation specified by @scontext. + * The default SID is passed to the MLS layer to be used to allow + * kernel labeling of the MLS field if the MLS field is not present + * (for upgrading to MLS without full relabel). + * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient + * memory is available, or 0 on success. + */ +int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) +{ + return security_context_to_sid_core(scontext, scontext_len, + sid, def_sid); +} + static int compute_sid_handle_invalid_context( struct context *scontext, struct context *tcontext, |