@@ -736,6 +736,7 @@ enum {
SOCKET_URING_OP_SIOCINQ = 0,
SOCKET_URING_OP_SIOCOUTQ,
SOCKET_URING_OP_GETSOCKOPT,
+ SOCKET_URING_OP_SETSOCKOPT,
};
#ifdef __cplusplus
@@ -207,6 +207,39 @@ static inline int io_uring_cmd_getsockopt(struct socket *sock,
return optlen;
}
+static inline int io_uring_cmd_setsockopt(struct socket *sock,
+ struct io_uring_cmd *cmd)
+{
+ void __user *optval = u64_to_user_ptr(READ_ONCE(cmd->sqe->optval));
+ int optname = READ_ONCE(cmd->sqe->optname);
+ int optlen = READ_ONCE(cmd->sqe->optlen);
+ int level = READ_ONCE(cmd->sqe->level);
+ void *koptval;
+ int err;
+
+ err = security_socket_setsockopt(sock, level, optname);
+ if (err)
+ return err;
+
+ koptval = kmalloc(optlen, GFP_KERNEL);
+ if (!koptval)
+ return -ENOMEM;
+
+ err = copy_from_user(koptval, optval, optlen);
+ if (err)
+ goto fail;
+
+ err = -EOPNOTSUPP;
+ if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock)) {
+ err = sock_setsockopt(sock, level, optname,
+ KERNEL_SOCKPTR(koptval), optlen);
+ }
+
+fail:
+ kfree(koptval);
+ return err;
+}
+
int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
{
struct socket *sock = cmd->file->private_data;
@@ -230,6 +263,8 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags)
return arg;
case SOCKET_URING_OP_GETSOCKOPT:
return io_uring_cmd_getsockopt(sock, cmd);
+ case SOCKET_URING_OP_SETSOCKOPT:
+ return io_uring_cmd_setsockopt(sock, cmd);
default:
return -EOPNOTSUPP;
}
Add initial support for SOCKET_URING_OP_SETSOCKOPT. This new command is similar to setsockopt. This initial implementation just cares about SOL_SOCKET level for now. The next patch implements the generic case. Function io_uring_cmd_setsockopt() is inspired by the function __sys_setsockopt(). "optval" is currently copied to kernel space in io_uring_cmd_setsockopt(), so, the setsockopt() protocol callbacks operate on kernel space memory after io_uring handlers. Important to say that userspace needs to keep the pointer's memory alive until the operation is completed. Signed-off-by: Breno Leitao <leitao@debian.org> --- include/uapi/linux/io_uring.h | 1 + io_uring/uring_cmd.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+)