Merge tag 'pull-path' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-block.git] / security / selinux / hooks.c
index c8168d19fb9627aa0e601b94055add82e530c1be..f553c370397eeb16c2dc7509d97f733add15cfba 100644 (file)
@@ -91,6 +91,7 @@
 #include <uapi/linux/mount.h>
 #include <linux/fsnotify.h>
 #include <linux/fanotify.h>
+#include <linux/io_uring.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -4221,6 +4222,14 @@ static void selinux_task_to_inode(struct task_struct *p,
        spin_unlock(&isec->lock);
 }
 
+static int selinux_userns_create(const struct cred *cred)
+{
+       u32 sid = current_sid();
+
+       return avc_has_perm(&selinux_state, sid, sid, SECCLASS_USER_NAMESPACE,
+                                               USER_NAMESPACE__CREATE, NULL);
+}
+
 /* Returns error only if unable to parse addresses */
 static int selinux_parse_skb_ipv4(struct sk_buff *skb,
                        struct common_audit_data *ad, u8 *proto)
@@ -5986,7 +5995,6 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
-       int rc;
 
        isec = selinux_ipc(msq);
        ipc_init_security(isec, SECCLASS_MSGQ);
@@ -5994,10 +6002,9 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->key;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, isec->sid, SECCLASS_MSGQ,
-                         MSGQ__CREATE, &ad);
-       return rc;
+       return avc_has_perm(&selinux_state,
+                           sid, isec->sid, SECCLASS_MSGQ,
+                           MSGQ__CREATE, &ad);
 }
 
 static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
@@ -6125,7 +6132,6 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
-       int rc;
 
        isec = selinux_ipc(shp);
        ipc_init_security(isec, SECCLASS_SHM);
@@ -6133,10 +6139,9 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->key;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, isec->sid, SECCLASS_SHM,
-                         SHM__CREATE, &ad);
-       return rc;
+       return avc_has_perm(&selinux_state,
+                           sid, isec->sid, SECCLASS_SHM,
+                           SHM__CREATE, &ad);
 }
 
 static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
@@ -6210,7 +6215,6 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
        u32 sid = current_sid();
-       int rc;
 
        isec = selinux_ipc(sma);
        ipc_init_security(isec, SECCLASS_SEM);
@@ -6218,10 +6222,9 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
        ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->key;
 
-       rc = avc_has_perm(&selinux_state,
-                         sid, isec->sid, SECCLASS_SEM,
-                         SEM__CREATE, &ad);
-       return rc;
+       return avc_has_perm(&selinux_state,
+                           sid, isec->sid, SECCLASS_SEM,
+                           SEM__CREATE, &ad);
 }
 
 static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
@@ -6987,6 +6990,28 @@ static int selinux_uring_sqpoll(void)
        return avc_has_perm(&selinux_state, sid, sid,
                            SECCLASS_IO_URING, IO_URING__SQPOLL, NULL);
 }
+
+/**
+ * selinux_uring_cmd - check if IORING_OP_URING_CMD is allowed
+ * @ioucmd: the io_uring command structure
+ *
+ * Check to see if the current domain is allowed to execute an
+ * IORING_OP_URING_CMD against the device/file specified in @ioucmd.
+ *
+ */
+static int selinux_uring_cmd(struct io_uring_cmd *ioucmd)
+{
+       struct file *file = ioucmd->file;
+       struct inode *inode = file_inode(file);
+       struct inode_security_struct *isec = selinux_inode(inode);
+       struct common_audit_data ad;
+
+       ad.type = LSM_AUDIT_DATA_FILE;
+       ad.u.file = file;
+
+       return avc_has_perm(&selinux_state, current_sid(), isec->sid,
+                           SECCLASS_IO_URING, IO_URING__CMD, &ad);
+}
 #endif /* CONFIG_IO_URING */
 
 /*
@@ -7111,6 +7136,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
        LSM_HOOK_INIT(task_kill, selinux_task_kill),
        LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
+       LSM_HOOK_INIT(userns_create, selinux_userns_create),
 
        LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
        LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
@@ -7231,6 +7257,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
 #ifdef CONFIG_IO_URING
        LSM_HOOK_INIT(uring_override_creds, selinux_uring_override_creds),
        LSM_HOOK_INIT(uring_sqpoll, selinux_uring_sqpoll),
+       LSM_HOOK_INIT(uring_cmd, selinux_uring_cmd),
 #endif
 
        /*