lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <f77ac379ddb6a67c3ac6a9dc54430142ead07c6f.1576336565.git.asml.silence@gmail.com>
Date:   Sat, 14 Dec 2019 18:29:49 +0300
From:   Pavel Begunkov <asml.silence@...il.com>
To:     Jens Axboe <axboe@...nel.dk>, io-uring@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: [RFC PATCH] io_uring: add support for IORING_OP_IOCTL

This works almost like ioctl(2), except it doesn't support a bunch of
common opcodes, (e.g. FIOCLEX and FIBMAP, see ioctl.c), and goes
straight to a device specific implementation.

The case in mind is dma-buf, drm and other ioctl-centric interfaces.

Not-yet Signed-off-by: Pavel Begunkov <asml.silence@...il.com>
---

It clearly needs some testing first, though works fine with dma-buf,
but I'd like to discuss whether the use cases are convincing enough,
and is it ok to desert some ioctl opcodes. For the last point it's
fairly easy to add, maybe except three requiring fd (e.g. FIOCLEX)

P.S. Probably, it won't benefit enough to consider using io_uring
in drm/mesa, but anyway.

 fs/io_uring.c                 | 33 +++++++++++++++++++++++++++++++++
 include/uapi/linux/io_uring.h |  7 ++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 5dfc805ec31c..6269c51dd02f 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -72,6 +72,7 @@
 #include <linux/highmem.h>
 #include <linux/namei.h>
 #include <linux/fsnotify.h>
+#include <linux/security.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/io_uring.h>
@@ -3164,6 +3165,35 @@ static int io_req_defer(struct io_kiocb *req)
 	return -EIOCBQUEUED;
 }
 
+static int io_ioctl(struct io_kiocb *req,
+		    struct io_kiocb **nxt, bool force_nonblock)
+{
+	const struct io_uring_sqe *sqe = req->sqe;
+	unsigned int cmd = READ_ONCE(sqe->ioctl_cmd);
+	unsigned long arg = READ_ONCE(sqe->ioctl_arg);
+	int ret;
+
+	if (!req->file)
+		return -EBADF;
+	if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
+		return -EINVAL;
+	if (unlikely(sqe->ioprio || sqe->addr || sqe->buf_index
+		|| sqe->rw_flags))
+		return -EINVAL;
+	if (force_nonblock)
+		return -EAGAIN;
+
+	ret = security_file_ioctl(req->file, cmd, arg);
+	if (!ret)
+		ret = (int)vfs_ioctl(req->file, cmd, arg);
+
+	if (ret < 0)
+		req_set_fail_links(req);
+	io_cqring_add_event(req, ret);
+	io_put_req_find_next(req, nxt);
+	return 0;
+}
+
 __attribute__((nonnull))
 static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt,
 			bool force_nonblock)
@@ -3237,6 +3267,9 @@ static int io_issue_sqe(struct io_kiocb *req, struct io_kiocb **nxt,
 	case IORING_OP_FILES_UPDATE:
 		ret = io_files_update(req, force_nonblock);
 		break;
+	case IORING_OP_IOCTL:
+		ret = io_ioctl(req, nxt, force_nonblock);
+		break;
 	default:
 		ret = -EINVAL;
 		break;
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index cafee41efbe5..88d38364746a 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -22,9 +22,13 @@ struct io_uring_sqe {
 	union {
 		__u64	off;	/* offset into file */
 		__u64	addr2;
+		__u64	ioctl_arg;
 	};
 	__u64	addr;		/* pointer to buffer or iovecs */
-	__u32	len;		/* buffer size or number of iovecs */
+	union {
+		__u32	len;	/* buffer size or number of iovecs */
+		__u32	ioctl_cmd;
+	};
 	union {
 		__kernel_rwf_t	rw_flags;
 		__u32		fsync_flags;
@@ -81,6 +85,7 @@ enum {
 	IORING_OP_OPENAT,
 	IORING_OP_CLOSE,
 	IORING_OP_FILES_UPDATE,
+	IORING_OP_IOCTL,
 
 	/* this goes last, obviously */
 	IORING_OP_LAST,
-- 
2.24.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ