summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2016-11-22 22:15:30 +1100
committerJames Morris <james.l.morris@oracle.com>2016-11-22 22:15:30 +1100
commit636e4625adb5a53ee7f6b019fa2e68f36cf96d93 (patch)
treef62ebf969f1bfeaf484276eed4f7b7169055e167 /security
parent185c0f26c0267d5978b5c30d3a04f90cb245cd76 (diff)
parent152f91d4d11a30106b9cc0b27b47e0e80b633ee8 (diff)
Merge remote branch 'smack/smack-for-4.10' into next
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack.h1
-rw-r--r--security/smack/smack_access.c7
-rw-r--r--security/smack/smack_lsm.c117
-rw-r--r--security/smack/smackfs.c3
4 files changed, 53 insertions, 75 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 51fd30192c08..77abe2efacae 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -336,7 +336,6 @@ extern int smack_ptrace_rule;
extern struct smack_known smack_known_floor;
extern struct smack_known smack_known_hat;
extern struct smack_known smack_known_huh;
-extern struct smack_known smack_known_invalid;
extern struct smack_known smack_known_star;
extern struct smack_known smack_known_web;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 23e5808a0970..356e3764cad9 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -36,11 +36,6 @@ struct smack_known smack_known_floor = {
.smk_secid = 5,
};
-struct smack_known smack_known_invalid = {
- .smk_known = "",
- .smk_secid = 6,
-};
-
struct smack_known smack_known_web = {
.smk_known = "@",
.smk_secid = 7,
@@ -615,7 +610,7 @@ struct smack_known *smack_from_secid(const u32 secid)
* of a secid that is not on the list.
*/
rcu_read_unlock();
- return &smack_known_invalid;
+ return &smack_known_huh;
}
/*
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 1cb060293505..4d90257d03ad 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -692,12 +692,12 @@ static int smack_parse_opts_str(char *options,
}
}
- opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_ATOMIC);
+ opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_KERNEL);
if (!opts->mnt_opts)
goto out_err;
opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
- GFP_ATOMIC);
+ GFP_KERNEL);
if (!opts->mnt_opts_flags) {
kfree(opts->mnt_opts);
goto out_err;
@@ -769,6 +769,31 @@ static int smack_set_mnt_opts(struct super_block *sb,
if (sp->smk_flags & SMK_SB_INITIALIZED)
return 0;
+ if (!smack_privileged(CAP_MAC_ADMIN)) {
+ /*
+ * Unprivileged mounts don't get to specify Smack values.
+ */
+ if (num_opts)
+ return -EPERM;
+ /*
+ * Unprivileged mounts get root and default from the caller.
+ */
+ skp = smk_of_current();
+ sp->smk_root = skp;
+ sp->smk_default = skp;
+ /*
+ * For a handful of fs types with no user-controlled
+ * backing store it's okay to trust security labels
+ * in the filesystem. The rest are untrusted.
+ */
+ if (sb->s_user_ns != &init_user_ns &&
+ sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
+ sb->s_magic != RAMFS_MAGIC) {
+ transmute = 1;
+ sp->smk_flags |= SMK_SB_UNTRUSTED;
+ }
+ }
+
sp->smk_flags |= SMK_SB_INITIALIZED;
for (i = 0; i < num_opts; i++) {
@@ -809,31 +834,6 @@ static int smack_set_mnt_opts(struct super_block *sb,
}
}
- if (!smack_privileged(CAP_MAC_ADMIN)) {
- /*
- * Unprivileged mounts don't get to specify Smack values.
- */
- if (num_opts)
- return -EPERM;
- /*
- * Unprivileged mounts get root and default from the caller.
- */
- skp = smk_of_current();
- sp->smk_root = skp;
- sp->smk_default = skp;
- /*
- * For a handful of fs types with no user-controlled
- * backing store it's okay to trust security labels
- * in the filesystem. The rest are untrusted.
- */
- if (sb->s_user_ns != &init_user_ns &&
- sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
- sb->s_magic != RAMFS_MAGIC) {
- transmute = 1;
- sp->smk_flags |= SMK_SB_UNTRUSTED;
- }
- }
-
/*
* Initialize the root inode.
*/
@@ -1384,20 +1384,14 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
skp = smk_import_entry(value, size);
if (!IS_ERR(skp))
isp->smk_inode = skp;
- else
- isp->smk_inode = &smack_known_invalid;
} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
skp = smk_import_entry(value, size);
if (!IS_ERR(skp))
isp->smk_task = skp;
- else
- isp->smk_task = &smack_known_invalid;
} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
skp = smk_import_entry(value, size);
if (!IS_ERR(skp))
isp->smk_mmap = skp;
- else
- isp->smk_mmap = &smack_known_invalid;
}
return;
@@ -2023,6 +2017,8 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
if (new_tsp == NULL)
return -ENOMEM;
+ new->security = new_tsp;
+
rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
if (rc != 0)
return rc;
@@ -2032,7 +2028,6 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
if (rc != 0)
return rc;
- new->security = new_tsp;
return 0;
}
@@ -2067,12 +2062,8 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
static int smack_kernel_act_as(struct cred *new, u32 secid)
{
struct task_smack *new_tsp = new->security;
- struct smack_known *skp = smack_from_secid(secid);
-
- if (skp == NULL)
- return -EINVAL;
- new_tsp->smk_task = skp;
+ new_tsp->smk_task = smack_from_secid(secid);
return 0;
}
@@ -2337,8 +2328,16 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
if (ssp == NULL)
return -ENOMEM;
- ssp->smk_in = skp;
- ssp->smk_out = skp;
+ /*
+ * Sockets created by kernel threads receive web label.
+ */
+ if (unlikely(current->flags & PF_KTHREAD)) {
+ ssp->smk_in = &smack_known_web;
+ ssp->smk_out = &smack_known_web;
+ } else {
+ ssp->smk_in = skp;
+ ssp->smk_out = skp;
+ }
ssp->smk_packet = NULL;
sk->sk_security = ssp;
@@ -2435,17 +2434,17 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
/*
+ * If the label is NULL the entry has
+ * been renounced. Ignore it.
+ */
+ if (snp->smk_label == NULL)
+ continue;
+ /*
* we break after finding the first match because
* the list is sorted from longest to shortest mask
* so we have found the most specific match
*/
for (found = 1, i = 0; i < 8; i++) {
- /*
- * If the label is NULL the entry has
- * been renounced. Ignore it.
- */
- if (snp->smk_label == NULL)
- continue;
if ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) !=
snp->smk_host.s6_addr16[i]) {
found = 0;
@@ -3661,10 +3660,11 @@ static int smack_setprocattr(struct task_struct *p, char *name,
return PTR_ERR(skp);
/*
- * No process is ever allowed the web ("@") label.
+ * No process is ever allowed the web ("@") label
+ * and the star ("*") label.
*/
- if (skp == &smack_known_web)
- return -EPERM;
+ if (skp == &smack_known_web || skp == &smack_known_star)
+ return -EINVAL;
if (!smack_privileged(CAP_MAC_ADMIN)) {
rc = -EPERM;
@@ -3884,21 +3884,11 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
return &smack_known_web;
return &smack_known_star;
}
- if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
+ if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
/*
* Looks like a fallback, which gives us a secid.
*/
- skp = smack_from_secid(sap->attr.secid);
- /*
- * This has got to be a bug because it is
- * impossible to specify a fallback without
- * specifying the label, which will ensure
- * it has a secid, and the only way to get a
- * secid is from a fallback.
- */
- BUG_ON(skp == NULL);
- return skp;
- }
+ return smack_from_secid(sap->attr.secid);
/*
* Without guidance regarding the smack value
* for the packet fall back on the network
@@ -4761,7 +4751,6 @@ static __init void init_smack_known_list(void)
mutex_init(&smack_known_hat.smk_rules_lock);
mutex_init(&smack_known_floor.smk_rules_lock);
mutex_init(&smack_known_star.smk_rules_lock);
- mutex_init(&smack_known_invalid.smk_rules_lock);
mutex_init(&smack_known_web.smk_rules_lock);
/*
* Initialize rule lists
@@ -4770,7 +4759,6 @@ static __init void init_smack_known_list(void)
INIT_LIST_HEAD(&smack_known_hat.smk_rules);
INIT_LIST_HEAD(&smack_known_star.smk_rules);
INIT_LIST_HEAD(&smack_known_floor.smk_rules);
- INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
INIT_LIST_HEAD(&smack_known_web.smk_rules);
/*
* Create the known labels list
@@ -4779,7 +4767,6 @@ static __init void init_smack_known_list(void)
smk_insert_entry(&smack_known_hat);
smk_insert_entry(&smack_known_star);
smk_insert_entry(&smack_known_floor);
- smk_insert_entry(&smack_known_invalid);
smk_insert_entry(&smack_known_web);
}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 6492fe96cae4..13743a01b35b 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -2998,9 +2998,6 @@ static int __init init_smk_fs(void)
rc = smk_preset_netlabel(&smack_known_huh);
if (err == 0 && rc < 0)
err = rc;
- rc = smk_preset_netlabel(&smack_known_invalid);
- if (err == 0 && rc < 0)
- err = rc;
rc = smk_preset_netlabel(&smack_known_star);
if (err == 0 && rc < 0)
err = rc;