aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack.h2
-rw-r--r--security/smack/smack_access.c17
-rw-r--r--security/smack/smack_lsm.c93
-rw-r--r--security/smack/smack_netfilter.c26
-rw-r--r--security/smack/smackfs.c11
5 files changed, 92 insertions, 57 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index c3cfbdf4944a..99c3422596ab 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -302,7 +302,7 @@ int smack_populate_secattr(struct smack_known *skp);
/*
* Shared data.
*/
-extern int smack_enabled;
+extern int smack_enabled __initdata;
extern int smack_cipso_direct;
extern int smack_cipso_mapped;
extern struct smack_known *smack_net_ambient;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 1f391f6a3d47..d2186e2757be 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -81,23 +81,22 @@ int log_policy = SMACK_AUDIT_DENIED;
int smk_access_entry(char *subject_label, char *object_label,
struct list_head *rule_list)
{
- int may = -ENOENT;
struct smack_rule *srp;
list_for_each_entry_rcu(srp, rule_list, list) {
if (srp->smk_object->smk_known == object_label &&
srp->smk_subject->smk_known == subject_label) {
- may = srp->smk_access;
- break;
+ int may = srp->smk_access;
+ /*
+ * MAY_WRITE implies MAY_LOCK.
+ */
+ if ((may & MAY_WRITE) == MAY_WRITE)
+ may |= MAY_LOCK;
+ return may;
}
}
- /*
- * MAY_WRITE implies MAY_LOCK.
- */
- if ((may & MAY_WRITE) == MAY_WRITE)
- may |= MAY_LOCK;
- return may;
+ return -ENOENT;
}
/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 223a6da0e6dc..efd35b07c7f8 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -51,10 +51,12 @@
#define SMK_RECEIVING 1
#define SMK_SENDING 2
+#ifdef SMACK_IPV6_PORT_LABELING
static DEFINE_MUTEX(smack_ipv6_lock);
static LIST_HEAD(smk_ipv6_port_list);
+#endif
struct kmem_cache *smack_rule_cache;
-int smack_enabled;
+int smack_enabled __initdata;
#define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s}
static struct {
@@ -389,7 +391,7 @@ static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
/**
* smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
- * @mode - input mode in form of PTRACE_MODE_*
+ * @mode: input mode in form of PTRACE_MODE_*
*
* Returns a converted MAY_* mode usable by smack rules
*/
@@ -1213,6 +1215,7 @@ static int smack_inode_getattr(const struct path *path)
/**
* smack_inode_setxattr - Smack check for setting xattrs
+ * @mnt_userns: active user namespace
* @dentry: the object
* @name: name of the attribute
* @value: value of the attribute
@@ -1339,6 +1342,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
/**
* smack_inode_removexattr - Smack check on removexattr
+ * @mnt_userns: active user namespace
* @dentry: the object
* @name: name of the attribute
*
@@ -1398,6 +1402,7 @@ static int smack_inode_removexattr(struct user_namespace *mnt_userns,
/**
* smack_inode_getsecurity - get smack xattrs
+ * @mnt_userns: active user namespace
* @inode: the object
* @name: attribute name
* @buffer: where to put the result
@@ -1619,13 +1624,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
}
/**
- * smack_mmap_file :
- * Check permissions for a mmap operation. The @file may be NULL, e.g.
- * if mapping anonymous memory.
- * @file contains the file structure for file to map (may be NULL).
- * @reqprot contains the protection requested by the application.
- * @prot contains the protection that will be applied by the kernel.
- * @flags contains the operational flags.
+ * smack_mmap_file - Check permissions for a mmap operation.
+ * @file: contains the file structure for file to map (may be NULL).
+ * @reqprot: contains the protection requested by the application.
+ * @prot: contains the protection that will be applied by the kernel.
+ * @flags: contains the operational flags.
+ *
+ * The @file may be NULL, e.g. if mapping anonymous memory.
+ *
* Return 0 if permission is granted.
*/
static int smack_mmap_file(struct file *file,
@@ -2016,7 +2022,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
const char *caller)
{
struct smk_audit_info ad;
- struct smack_known *skp = smk_of_task_struct_subj(p);
+ struct smack_known *skp = smk_of_task_struct_obj(p);
int rc;
smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
@@ -2603,7 +2609,6 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
mutex_unlock(&smack_ipv6_lock);
return;
}
-#endif
/**
* smk_ipv6_port_check - check Smack port access
@@ -2666,6 +2671,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
return smk_ipv6_check(skp, object, address, act);
}
+#endif
/**
* smack_inode_setsecurity - set smack xattrs
@@ -2852,8 +2858,9 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
SMK_CONNECTING);
}
- if (__is_defined(SMACK_IPV6_PORT_LABELING))
- rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
+#ifdef SMACK_IPV6_PORT_LABELING
+ rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
+#endif
return rc;
}
@@ -3051,7 +3058,7 @@ static int smack_sem_associate(struct kern_ipc_perm *isp, int semflg)
}
/**
- * smack_sem_shmctl - Smack access check for sem
+ * smack_sem_semctl - Smack access check for sem
* @isp: the object
* @cmd: what it wants to do
*
@@ -3197,7 +3204,7 @@ static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg
}
/**
- * smack_msg_queue_msgsnd - Smack access check for msg_queue
+ * smack_msg_queue_msgrcv - Smack access check for msg_queue
* @isp: the object
* @msg: unused
* @target: unused
@@ -3206,8 +3213,10 @@ static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg
*
* Returns 0 if current has read and write access, error code otherwise
*/
-static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp, struct msg_msg *msg,
- struct task_struct *target, long type, int mode)
+static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp,
+ struct msg_msg *msg,
+ struct task_struct *target, long type,
+ int mode)
{
return smk_curacc_msq(isp, MAY_READWRITE);
}
@@ -3480,7 +3489,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
*/
static int smack_getprocattr(struct task_struct *p, char *name, char **value)
{
- struct smack_known *skp = smk_of_task_struct_subj(p);
+ struct smack_known *skp = smk_of_task_struct_obj(p);
char *cp;
int slen;
@@ -4634,7 +4643,7 @@ static int smack_inode_copy_up(struct dentry *dentry, struct cred **new)
/*
* Get label from overlay inode and set it in create_sid
*/
- isp = smack_inode(d_inode(dentry->d_parent));
+ isp = smack_inode(d_inode(dentry));
skp = isp->smk_inode;
tsp->smk_task = skp;
*new = new_creds;
@@ -4691,6 +4700,48 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
return 0;
}
+#ifdef CONFIG_IO_URING
+/**
+ * smack_uring_override_creds - Is io_uring cred override allowed?
+ * @new: the target creds
+ *
+ * Check to see if the current task is allowed to override it's credentials
+ * to service an io_uring operation.
+ */
+static int smack_uring_override_creds(const struct cred *new)
+{
+ struct task_smack *tsp = smack_cred(current_cred());
+ struct task_smack *nsp = smack_cred(new);
+
+ /*
+ * Allow the degenerate case where the new Smack value is
+ * the same as the current Smack value.
+ */
+ if (tsp->smk_task == nsp->smk_task)
+ return 0;
+
+ if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()))
+ return 0;
+
+ return -EPERM;
+}
+
+/**
+ * smack_uring_sqpoll - check if a io_uring polling thread can be created
+ *
+ * Check to see if the current task is allowed to create a new io_uring
+ * kernel polling thread.
+ */
+static int smack_uring_sqpoll(void)
+{
+ if (smack_privileged_cred(CAP_MAC_ADMIN, current_cred()))
+ return 0;
+
+ return -EPERM;
+}
+
+#endif /* CONFIG_IO_URING */
+
struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
.lbs_cred = sizeof(struct task_smack),
.lbs_file = sizeof(struct smack_known *),
@@ -4843,6 +4894,10 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(inode_copy_up, smack_inode_copy_up),
LSM_HOOK_INIT(inode_copy_up_xattr, smack_inode_copy_up_xattr),
LSM_HOOK_INIT(dentry_create_files_as, smack_dentry_create_files_as),
+#ifdef CONFIG_IO_URING
+ LSM_HOOK_INIT(uring_override_creds, smack_uring_override_creds),
+ LSM_HOOK_INIT(uring_sqpoll, smack_uring_sqpoll),
+#endif
};
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c
index fc7399b45373..b945c1d3a743 100644
--- a/security/smack/smack_netfilter.c
+++ b/security/smack/smack_netfilter.c
@@ -18,27 +18,7 @@
#include <net/net_namespace.h>
#include "smack.h"
-#if IS_ENABLED(CONFIG_IPV6)
-
-static unsigned int smack_ipv6_output(void *priv,
- struct sk_buff *skb,
- const struct nf_hook_state *state)
-{
- struct sock *sk = skb_to_full_sk(skb);
- struct socket_smack *ssp;
- struct smack_known *skp;
-
- if (sk && sk->sk_security) {
- ssp = sk->sk_security;
- skp = ssp->smk_out;
- skb->secmark = skp->smk_secid;
- }
-
- return NF_ACCEPT;
-}
-#endif /* IPV6 */
-
-static unsigned int smack_ipv4_output(void *priv,
+static unsigned int smack_ip_output(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
@@ -57,14 +37,14 @@ static unsigned int smack_ipv4_output(void *priv,
static const struct nf_hook_ops smack_nf_ops[] = {
{
- .hook = smack_ipv4_output,
+ .hook = smack_ip_output,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_SELINUX_FIRST,
},
#if IS_ENABLED(CONFIG_IPV6)
{
- .hook = smack_ipv6_output,
+ .hook = smack_ip_output,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_SELINUX_FIRST,
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 3a75d2a8f517..658eab05599e 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -693,9 +693,7 @@ static void smk_cipso_doi(void)
printk(KERN_WARNING "%s:%d remove rc = %d\n",
__func__, __LINE__, rc);
- doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
- if (doip == NULL)
- panic("smack: Failed to initialize cipso DOI.\n");
+ doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL | __GFP_NOFAIL);
doip->map.std = NULL;
doip->doi = smk_cipso_doi_value;
doip->type = CIPSO_V4_MAP_PASS;
@@ -714,7 +712,7 @@ static void smk_cipso_doi(void)
if (rc != 0) {
printk(KERN_WARNING "%s:%d map add rc = %d\n",
__func__, __LINE__, rc);
- kfree(doip);
+ netlbl_cfg_cipsov4_del(doip->doi, &nai);
return;
}
}
@@ -831,6 +829,7 @@ static int smk_open_cipso(struct inode *inode, struct file *file)
static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
size_t count, loff_t *ppos, int format)
{
+ struct netlbl_lsm_catmap *old_cat;
struct smack_known *skp;
struct netlbl_lsm_secattr ncats;
char mapcatset[SMK_CIPSOLEN];
@@ -920,9 +919,11 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
if (rc >= 0) {
- netlbl_catmap_free(skp->smk_netlabel.attr.mls.cat);
+ old_cat = skp->smk_netlabel.attr.mls.cat;
skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
+ synchronize_rcu();
+ netlbl_catmap_free(old_cat);
rc = count;
/*
* This mapping may have been cached, so clear the cache.

Privacy Policy