Commit 636e4625 authored by James Morris's avatar James Morris

Merge remote branch 'smack/smack-for-4.10' into next

parents 185c0f26 152f91d4
...@@ -336,7 +336,6 @@ extern int smack_ptrace_rule; ...@@ -336,7 +336,6 @@ extern int smack_ptrace_rule;
extern struct smack_known smack_known_floor; extern struct smack_known smack_known_floor;
extern struct smack_known smack_known_hat; extern struct smack_known smack_known_hat;
extern struct smack_known smack_known_huh; 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_star;
extern struct smack_known smack_known_web; extern struct smack_known smack_known_web;
......
...@@ -36,11 +36,6 @@ struct smack_known smack_known_floor = { ...@@ -36,11 +36,6 @@ struct smack_known smack_known_floor = {
.smk_secid = 5, .smk_secid = 5,
}; };
struct smack_known smack_known_invalid = {
.smk_known = "",
.smk_secid = 6,
};
struct smack_known smack_known_web = { struct smack_known smack_known_web = {
.smk_known = "@", .smk_known = "@",
.smk_secid = 7, .smk_secid = 7,
...@@ -615,7 +610,7 @@ struct smack_known *smack_from_secid(const u32 secid) ...@@ -615,7 +610,7 @@ struct smack_known *smack_from_secid(const u32 secid)
* of a secid that is not on the list. * of a secid that is not on the list.
*/ */
rcu_read_unlock(); rcu_read_unlock();
return &smack_known_invalid; return &smack_known_huh;
} }
/* /*
......
...@@ -692,12 +692,12 @@ static int smack_parse_opts_str(char *options, ...@@ -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) if (!opts->mnt_opts)
goto out_err; goto out_err;
opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int), opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
GFP_ATOMIC); GFP_KERNEL);
if (!opts->mnt_opts_flags) { if (!opts->mnt_opts_flags) {
kfree(opts->mnt_opts); kfree(opts->mnt_opts);
goto out_err; goto out_err;
...@@ -769,6 +769,31 @@ static int smack_set_mnt_opts(struct super_block *sb, ...@@ -769,6 +769,31 @@ static int smack_set_mnt_opts(struct super_block *sb,
if (sp->smk_flags & SMK_SB_INITIALIZED) if (sp->smk_flags & SMK_SB_INITIALIZED)
return 0; 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; sp->smk_flags |= SMK_SB_INITIALIZED;
for (i = 0; i < num_opts; i++) { for (i = 0; i < num_opts; i++) {
...@@ -809,31 +834,6 @@ static int smack_set_mnt_opts(struct super_block *sb, ...@@ -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. * Initialize the root inode.
*/ */
...@@ -1384,20 +1384,14 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, ...@@ -1384,20 +1384,14 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
skp = smk_import_entry(value, size); skp = smk_import_entry(value, size);
if (!IS_ERR(skp)) if (!IS_ERR(skp))
isp->smk_inode = skp; isp->smk_inode = skp;
else
isp->smk_inode = &smack_known_invalid;
} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
skp = smk_import_entry(value, size); skp = smk_import_entry(value, size);
if (!IS_ERR(skp)) if (!IS_ERR(skp))
isp->smk_task = skp; isp->smk_task = skp;
else
isp->smk_task = &smack_known_invalid;
} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
skp = smk_import_entry(value, size); skp = smk_import_entry(value, size);
if (!IS_ERR(skp)) if (!IS_ERR(skp))
isp->smk_mmap = skp; isp->smk_mmap = skp;
else
isp->smk_mmap = &smack_known_invalid;
} }
return; return;
...@@ -2023,6 +2017,8 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old, ...@@ -2023,6 +2017,8 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
if (new_tsp == NULL) if (new_tsp == NULL)
return -ENOMEM; return -ENOMEM;
new->security = new_tsp;
rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp); rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
if (rc != 0) if (rc != 0)
return rc; return rc;
...@@ -2032,7 +2028,6 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old, ...@@ -2032,7 +2028,6 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
if (rc != 0) if (rc != 0)
return rc; return rc;
new->security = new_tsp;
return 0; return 0;
} }
...@@ -2067,12 +2062,8 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old) ...@@ -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) static int smack_kernel_act_as(struct cred *new, u32 secid)
{ {
struct task_smack *new_tsp = new->security; 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; return 0;
} }
...@@ -2337,8 +2328,16 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) ...@@ -2337,8 +2328,16 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
if (ssp == NULL) if (ssp == NULL)
return -ENOMEM; return -ENOMEM;
/*
* 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_in = skp;
ssp->smk_out = skp; ssp->smk_out = skp;
}
ssp->smk_packet = NULL; ssp->smk_packet = NULL;
sk->sk_security = ssp; sk->sk_security = ssp;
...@@ -2434,18 +2433,18 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip) ...@@ -2434,18 +2433,18 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
return NULL; return NULL;
list_for_each_entry_rcu(snp, &smk_net6addr_list, list) { list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
/*
* 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 * If the label is NULL the entry has
* been renounced. Ignore it. * been renounced. Ignore it.
*/ */
if (snp->smk_label == NULL) if (snp->smk_label == NULL)
continue; 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 ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) != if ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) !=
snp->smk_host.s6_addr16[i]) { snp->smk_host.s6_addr16[i]) {
found = 0; found = 0;
...@@ -3661,10 +3660,11 @@ static int smack_setprocattr(struct task_struct *p, char *name, ...@@ -3661,10 +3660,11 @@ static int smack_setprocattr(struct task_struct *p, char *name,
return PTR_ERR(skp); 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) if (skp == &smack_known_web || skp == &smack_known_star)
return -EPERM; return -EINVAL;
if (!smack_privileged(CAP_MAC_ADMIN)) { if (!smack_privileged(CAP_MAC_ADMIN)) {
rc = -EPERM; rc = -EPERM;
...@@ -3884,21 +3884,11 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, ...@@ -3884,21 +3884,11 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
return &smack_known_web; return &smack_known_web;
return &smack_known_star; 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. * Looks like a fallback, which gives us a secid.
*/ */
skp = smack_from_secid(sap->attr.secid); return 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;
}
/* /*
* Without guidance regarding the smack value * Without guidance regarding the smack value
* for the packet fall back on the network * for the packet fall back on the network
...@@ -4761,7 +4751,6 @@ static __init void init_smack_known_list(void) ...@@ -4761,7 +4751,6 @@ static __init void init_smack_known_list(void)
mutex_init(&smack_known_hat.smk_rules_lock); mutex_init(&smack_known_hat.smk_rules_lock);
mutex_init(&smack_known_floor.smk_rules_lock); mutex_init(&smack_known_floor.smk_rules_lock);
mutex_init(&smack_known_star.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); mutex_init(&smack_known_web.smk_rules_lock);
/* /*
* Initialize rule lists * Initialize rule lists
...@@ -4770,7 +4759,6 @@ static __init void init_smack_known_list(void) ...@@ -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_hat.smk_rules);
INIT_LIST_HEAD(&smack_known_star.smk_rules); INIT_LIST_HEAD(&smack_known_star.smk_rules);
INIT_LIST_HEAD(&smack_known_floor.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); INIT_LIST_HEAD(&smack_known_web.smk_rules);
/* /*
* Create the known labels list * Create the known labels list
...@@ -4779,7 +4767,6 @@ static __init void init_smack_known_list(void) ...@@ -4779,7 +4767,6 @@ static __init void init_smack_known_list(void)
smk_insert_entry(&smack_known_hat); smk_insert_entry(&smack_known_hat);
smk_insert_entry(&smack_known_star); smk_insert_entry(&smack_known_star);
smk_insert_entry(&smack_known_floor); smk_insert_entry(&smack_known_floor);
smk_insert_entry(&smack_known_invalid);
smk_insert_entry(&smack_known_web); smk_insert_entry(&smack_known_web);
} }
......
...@@ -2996,9 +2996,6 @@ static int __init init_smk_fs(void) ...@@ -2996,9 +2996,6 @@ static int __init init_smk_fs(void)
if (err == 0 && rc < 0) if (err == 0 && rc < 0)
err = rc; err = rc;
rc = smk_preset_netlabel(&smack_known_huh); 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) if (err == 0 && rc < 0)
err = rc; err = rc;
rc = smk_preset_netlabel(&smack_known_star); rc = smk_preset_netlabel(&smack_known_star);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment