Commit 9c9d1896 authored by Linus Torvalds's avatar Linus Torvalds

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
parents dcf8e563 dd937340
......@@ -480,6 +480,11 @@ static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
}
static int uring_cmd_null(struct io_uring_cmd *ioucmd, unsigned int issue_flags)
{
return 0;
}
static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
{
size_t written = 0;
......@@ -663,6 +668,7 @@ static const struct file_operations null_fops = {
.read_iter = read_iter_null,
.write_iter = write_iter_null,
.splice_write = splice_write_null,
.uring_cmd = uring_cmd_null,
};
static const struct file_operations __maybe_unused port_fops = {
......
......@@ -407,4 +407,5 @@ LSM_HOOK(int, 0, perf_event_write, struct perf_event *event)
#ifdef CONFIG_IO_URING
LSM_HOOK(int, 0, uring_override_creds, const struct cred *new)
LSM_HOOK(int, 0, uring_sqpoll, void)
LSM_HOOK(int, 0, uring_cmd, struct io_uring_cmd *ioucmd)
#endif /* CONFIG_IO_URING */
......@@ -1582,6 +1582,9 @@
* Check whether the current task is allowed to spawn a io_uring polling
* thread (IORING_SETUP_SQPOLL).
*
* @uring_cmd:
* Check whether the file_operations uring_cmd is allowed to run.
*
*/
union security_list_options {
#define LSM_HOOK(RET, DEFAULT, NAME, ...) RET (*NAME)(__VA_ARGS__);
......
......@@ -2060,6 +2060,7 @@ static inline int security_perf_event_write(struct perf_event *event)
#ifdef CONFIG_SECURITY
extern int security_uring_override_creds(const struct cred *new);
extern int security_uring_sqpoll(void);
extern int security_uring_cmd(struct io_uring_cmd *ioucmd);
#else
static inline int security_uring_override_creds(const struct cred *new)
{
......@@ -2069,6 +2070,10 @@ static inline int security_uring_sqpoll(void)
{
return 0;
}
static inline int security_uring_cmd(struct io_uring_cmd *ioucmd)
{
return 0;
}
#endif /* CONFIG_SECURITY */
#endif /* CONFIG_IO_URING */
......
......@@ -3,6 +3,7 @@
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/io_uring.h>
#include <linux/security.h>
#include <uapi/linux/io_uring.h>
......@@ -88,6 +89,10 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
if (!req->file->f_op->uring_cmd)
return -EOPNOTSUPP;
ret = security_uring_cmd(ioucmd);
if (ret)
return ret;
if (ctx->flags & IORING_SETUP_SQE128)
issue_flags |= IO_URING_F_SQE128;
if (ctx->flags & IORING_SETUP_CQE32)
......
......@@ -2660,4 +2660,8 @@ int security_uring_sqpoll(void)
{
return call_int_hook(uring_sqpoll, 0);
}
int security_uring_cmd(struct io_uring_cmd *ioucmd)
{
return call_int_hook(uring_cmd, 0, ioucmd);
}
#endif /* CONFIG_IO_URING */
......@@ -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"
......@@ -6987,6 +6988,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 */
/*
......@@ -7231,6 +7254,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
/*
......
......@@ -253,7 +253,7 @@ const struct security_class_mapping secclass_map[] = {
{ "anon_inode",
{ COMMON_FILE_PERMS, NULL } },
{ "io_uring",
{ "override_creds", "sqpoll", NULL } },
{ "override_creds", "sqpoll", "cmd", NULL } },
{ NULL }
};
......
......@@ -42,6 +42,7 @@
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/watch_queue.h>
#include <linux/io_uring.h>
#include "smack.h"
#define TRANS_TRUE "TRUE"
......@@ -4732,6 +4733,36 @@ static int smack_uring_sqpoll(void)
return -EPERM;
}
/**
* smack_uring_cmd - check on file operations for io_uring
* @ioucmd: the command in question
*
* Make a best guess about whether a io_uring "command" should
* be allowed. Use the same logic used for determining if the
* file could be opened for read in the absence of better criteria.
*/
static int smack_uring_cmd(struct io_uring_cmd *ioucmd)
{
struct file *file = ioucmd->file;
struct smk_audit_info ad;
struct task_smack *tsp;
struct inode *inode;
int rc;
if (!file)
return -EINVAL;
tsp = smack_cred(file->f_cred);
inode = file_inode(file);
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, file->f_path);
rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad);
rc = smk_bu_credfile(file->f_cred, file, MAY_READ, rc);
return rc;
}
#endif /* CONFIG_IO_URING */
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 = {
#ifdef CONFIG_IO_URING
LSM_HOOK_INIT(uring_override_creds, smack_uring_override_creds),
LSM_HOOK_INIT(uring_sqpoll, smack_uring_sqpoll),
LSM_HOOK_INIT(uring_cmd, smack_uring_cmd),
#endif
};
......
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