Skip to content

Commit 9c9d189

Browse files
committed
Merge tag 'lsm-pr-20220829' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm
Pull LSM support for IORING_OP_URING_CMD from Paul Moore: "Add SELinux and Smack controls to the io_uring IORING_OP_URING_CMD. These are necessary as without them the IORING_OP_URING_CMD remains outside the purview of the LSMs (Luis' LSM patch, Casey's Smack patch, and my SELinux patch). They have been discussed at length with the io_uring folks, and Jens has given his thumbs-up on the relevant patches (see the commit descriptions). There is one patch that is not strictly necessary, but it makes testing much easier and is very trivial: the /dev/null IORING_OP_URING_CMD patch." * tag 'lsm-pr-20220829' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: Smack: Provide read control for io_uring_cmd /dev/null: add IORING_OP_URING_CMD support selinux: implement the security_uring_cmd() LSM hook lsm,io_uring: add LSM hooks for the new uring_cmd file op
2 parents dcf8e56 + dd93734 commit 9c9d189

File tree

9 files changed

+81
-1
lines changed

9 files changed

+81
-1
lines changed

drivers/char/mem.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@ static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
480480
return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
481481
}
482482

483+
static int uring_cmd_null(struct io_uring_cmd *ioucmd, unsigned int issue_flags)
484+
{
485+
return 0;
486+
}
487+
483488
static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
484489
{
485490
size_t written = 0;
@@ -663,6 +668,7 @@ static const struct file_operations null_fops = {
663668
.read_iter = read_iter_null,
664669
.write_iter = write_iter_null,
665670
.splice_write = splice_write_null,
671+
.uring_cmd = uring_cmd_null,
666672
};
667673

668674
static const struct file_operations __maybe_unused port_fops = {

include/linux/lsm_hook_defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,5 @@ LSM_HOOK(int, 0, perf_event_write, struct perf_event *event)
407407
#ifdef CONFIG_IO_URING
408408
LSM_HOOK(int, 0, uring_override_creds, const struct cred *new)
409409
LSM_HOOK(int, 0, uring_sqpoll, void)
410+
LSM_HOOK(int, 0, uring_cmd, struct io_uring_cmd *ioucmd)
410411
#endif /* CONFIG_IO_URING */

include/linux/lsm_hooks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,6 +1582,9 @@
15821582
* Check whether the current task is allowed to spawn a io_uring polling
15831583
* thread (IORING_SETUP_SQPOLL).
15841584
*
1585+
* @uring_cmd:
1586+
* Check whether the file_operations uring_cmd is allowed to run.
1587+
*
15851588
*/
15861589
union security_list_options {
15871590
#define LSM_HOOK(RET, DEFAULT, NAME, ...) RET (*NAME)(__VA_ARGS__);

include/linux/security.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,7 @@ static inline int security_perf_event_write(struct perf_event *event)
20602060
#ifdef CONFIG_SECURITY
20612061
extern int security_uring_override_creds(const struct cred *new);
20622062
extern int security_uring_sqpoll(void);
2063+
extern int security_uring_cmd(struct io_uring_cmd *ioucmd);
20632064
#else
20642065
static inline int security_uring_override_creds(const struct cred *new)
20652066
{
@@ -2069,6 +2070,10 @@ static inline int security_uring_sqpoll(void)
20692070
{
20702071
return 0;
20712072
}
2073+
static inline int security_uring_cmd(struct io_uring_cmd *ioucmd)
2074+
{
2075+
return 0;
2076+
}
20722077
#endif /* CONFIG_SECURITY */
20732078
#endif /* CONFIG_IO_URING */
20742079

io_uring/uring_cmd.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <linux/errno.h>
44
#include <linux/file.h>
55
#include <linux/io_uring.h>
6+
#include <linux/security.h>
67

78
#include <uapi/linux/io_uring.h>
89

@@ -88,6 +89,10 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
8889
if (!req->file->f_op->uring_cmd)
8990
return -EOPNOTSUPP;
9091

92+
ret = security_uring_cmd(ioucmd);
93+
if (ret)
94+
return ret;
95+
9196
if (ctx->flags & IORING_SETUP_SQE128)
9297
issue_flags |= IO_URING_F_SQE128;
9398
if (ctx->flags & IORING_SETUP_CQE32)

security/security.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2660,4 +2660,8 @@ int security_uring_sqpoll(void)
26602660
{
26612661
return call_int_hook(uring_sqpoll, 0);
26622662
}
2663+
int security_uring_cmd(struct io_uring_cmd *ioucmd)
2664+
{
2665+
return call_int_hook(uring_cmd, 0, ioucmd);
2666+
}
26632667
#endif /* CONFIG_IO_URING */

security/selinux/hooks.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#include <uapi/linux/mount.h>
9292
#include <linux/fsnotify.h>
9393
#include <linux/fanotify.h>
94+
#include <linux/io_uring.h>
9495

9596
#include "avc.h"
9697
#include "objsec.h"
@@ -6987,6 +6988,28 @@ static int selinux_uring_sqpoll(void)
69876988
return avc_has_perm(&selinux_state, sid, sid,
69886989
SECCLASS_IO_URING, IO_URING__SQPOLL, NULL);
69896990
}
6991+
6992+
/**
6993+
* selinux_uring_cmd - check if IORING_OP_URING_CMD is allowed
6994+
* @ioucmd: the io_uring command structure
6995+
*
6996+
* Check to see if the current domain is allowed to execute an
6997+
* IORING_OP_URING_CMD against the device/file specified in @ioucmd.
6998+
*
6999+
*/
7000+
static int selinux_uring_cmd(struct io_uring_cmd *ioucmd)
7001+
{
7002+
struct file *file = ioucmd->file;
7003+
struct inode *inode = file_inode(file);
7004+
struct inode_security_struct *isec = selinux_inode(inode);
7005+
struct common_audit_data ad;
7006+
7007+
ad.type = LSM_AUDIT_DATA_FILE;
7008+
ad.u.file = file;
7009+
7010+
return avc_has_perm(&selinux_state, current_sid(), isec->sid,
7011+
SECCLASS_IO_URING, IO_URING__CMD, &ad);
7012+
}
69907013
#endif /* CONFIG_IO_URING */
69917014

69927015
/*
@@ -7231,6 +7254,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
72317254
#ifdef CONFIG_IO_URING
72327255
LSM_HOOK_INIT(uring_override_creds, selinux_uring_override_creds),
72337256
LSM_HOOK_INIT(uring_sqpoll, selinux_uring_sqpoll),
7257+
LSM_HOOK_INIT(uring_cmd, selinux_uring_cmd),
72347258
#endif
72357259

72367260
/*

security/selinux/include/classmap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ const struct security_class_mapping secclass_map[] = {
253253
{ "anon_inode",
254254
{ COMMON_FILE_PERMS, NULL } },
255255
{ "io_uring",
256-
{ "override_creds", "sqpoll", NULL } },
256+
{ "override_creds", "sqpoll", "cmd", NULL } },
257257
{ NULL }
258258
};
259259

security/smack/smack_lsm.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <linux/fs_context.h>
4343
#include <linux/fs_parser.h>
4444
#include <linux/watch_queue.h>
45+
#include <linux/io_uring.h>
4546
#include "smack.h"
4647

4748
#define TRANS_TRUE "TRUE"
@@ -4732,6 +4733,36 @@ static int smack_uring_sqpoll(void)
47324733
return -EPERM;
47334734
}
47344735

4736+
/**
4737+
* smack_uring_cmd - check on file operations for io_uring
4738+
* @ioucmd: the command in question
4739+
*
4740+
* Make a best guess about whether a io_uring "command" should
4741+
* be allowed. Use the same logic used for determining if the
4742+
* file could be opened for read in the absence of better criteria.
4743+
*/
4744+
static int smack_uring_cmd(struct io_uring_cmd *ioucmd)
4745+
{
4746+
struct file *file = ioucmd->file;
4747+
struct smk_audit_info ad;
4748+
struct task_smack *tsp;
4749+
struct inode *inode;
4750+
int rc;
4751+
4752+
if (!file)
4753+
return -EINVAL;
4754+
4755+
tsp = smack_cred(file->f_cred);
4756+
inode = file_inode(file);
4757+
4758+
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
4759+
smk_ad_setfield_u_fs_path(&ad, file->f_path);
4760+
rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad);
4761+
rc = smk_bu_credfile(file->f_cred, file, MAY_READ, rc);
4762+
4763+
return rc;
4764+
}
4765+
47354766
#endif /* CONFIG_IO_URING */
47364767

47374768
struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
@@ -4889,6 +4920,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
48894920
#ifdef CONFIG_IO_URING
48904921
LSM_HOOK_INIT(uring_override_creds, smack_uring_override_creds),
48914922
LSM_HOOK_INIT(uring_sqpoll, smack_uring_sqpoll),
4923+
LSM_HOOK_INIT(uring_cmd, smack_uring_cmd),
48924924
#endif
48934925
};
48944926

0 commit comments

Comments
 (0)