|
|
|
@@ -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;
|
|
|
|
@@ -2434,18 +2433,18 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|