Skip to content

Commit

Permalink
Merge tag 'io_uring-6.0-2022-08-13' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull io_uring fixes from Jens Axboe:

 - Regression fix for this merge window, fixing a wrong order of
   arguments for io_req_set_res() for passthru (Dylan)

 - Fix for the audit code leaking context memory (Peilin)

 - Ensure that provided buffers are memcg accounted (Pavel)

 - Correctly handle short zero-copy sends (Pavel)

 - Sparse warning fixes for the recvmsg multishot command (Dylan)

 - Error handling fix for passthru (Anuj)

 - Remove randomization of struct kiocb fields, to avoid it growing in
   size if re-arranged in such a fashion that it grows more holes or
   padding (Keith, Linus)

 - Small series improving type safety of the sqe fields (Stefan)

* tag 'io_uring-6.0-2022-08-13' of git://git.kernel.dk/linux-block:
  io_uring: add missing BUILD_BUG_ON() checks for new io_uring_sqe fields
  io_uring: make io_kiocb_to_cmd() typesafe
  fs: don't randomize struct kiocb fields
  io_uring: consistently make use of io_notif_to_data()
  io_uring: fix error handling for io_uring_cmd
  io_uring: fix io_recvmsg_prep_multishot sparse warnings
  io_uring/net: send retry for zerocopy
  io_uring: mem-account pbuf buckets
  audit, io_uring, io-wq: Fix memory leak in io_sq_thread() and io_wqe_worker()
  io_uring: pass correct parameters to io_req_set_res
  • Loading branch information
torvalds committed Aug 13, 2022
2 parents 69dac8e + 9c71d39 commit 1da8cf9
Show file tree
Hide file tree
Showing 26 changed files with 178 additions and 183 deletions.
5 changes: 0 additions & 5 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,6 @@ static inline int audit_signal_info(int sig, struct task_struct *t)
/* These are defined in auditsc.c */
/* Public API */
extern int audit_alloc(struct task_struct *task);
extern int audit_alloc_kernel(struct task_struct *task);
extern void __audit_free(struct task_struct *task);
extern void __audit_uring_entry(u8 op);
extern void __audit_uring_exit(int success, long code);
Expand Down Expand Up @@ -578,10 +577,6 @@ static inline int audit_alloc(struct task_struct *task)
{
return 0;
}
static inline int audit_alloc_kernel(struct task_struct *task)
{
return 0;
}
static inline void audit_free(struct task_struct *task)
{ }
static inline void audit_uring_entry(u8 op)
Expand Down
5 changes: 0 additions & 5 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,17 +340,12 @@ enum rw_hint {

struct kiocb {
struct file *ki_filp;

/* The 'ki_filp' pointer is shared in a union for aio */
randomized_struct_fields_start

loff_t ki_pos;
void (*ki_complete)(struct kiocb *iocb, long ret);
void *private;
int ki_flags;
u16 ki_ioprio; /* See linux/ioprio.h */
struct wait_page_queue *ki_waitq; /* for async buffered IO */
randomized_struct_fields_end
};

static inline bool is_sync_kiocb(struct kiocb *kiocb)
Expand Down
9 changes: 8 additions & 1 deletion include/linux/io_uring_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,14 @@ struct io_cmd_data {
__u8 data[56];
};

#define io_kiocb_to_cmd(req) ((void *) &(req)->cmd)
static inline void io_kiocb_cmd_sz_check(size_t cmd_sz)
{
BUILD_BUG_ON(cmd_sz > sizeof(struct io_cmd_data));
}
#define io_kiocb_to_cmd(req, cmd_type) ( \
io_kiocb_cmd_sz_check(sizeof(cmd_type)) , \
((cmd_type *)&(req)->cmd) \
)
#define cmd_to_io_kiocb(ptr) ((struct io_kiocb *) ptr)

struct io_kiocb {
Expand Down
8 changes: 4 additions & 4 deletions io_uring/advise.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct io_madvise {
int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
#if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
struct io_madvise *ma = io_kiocb_to_cmd(req);
struct io_madvise *ma = io_kiocb_to_cmd(req, struct io_madvise);

if (sqe->buf_index || sqe->off || sqe->splice_fd_in)
return -EINVAL;
Expand All @@ -48,7 +48,7 @@ int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
int io_madvise(struct io_kiocb *req, unsigned int issue_flags)
{
#if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
struct io_madvise *ma = io_kiocb_to_cmd(req);
struct io_madvise *ma = io_kiocb_to_cmd(req, struct io_madvise);
int ret;

if (issue_flags & IO_URING_F_NONBLOCK)
Expand All @@ -64,7 +64,7 @@ int io_madvise(struct io_kiocb *req, unsigned int issue_flags)

int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_fadvise *fa = io_kiocb_to_cmd(req);
struct io_fadvise *fa = io_kiocb_to_cmd(req, struct io_fadvise);

if (sqe->buf_index || sqe->addr || sqe->splice_fd_in)
return -EINVAL;
Expand All @@ -77,7 +77,7 @@ int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_fadvise(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_fadvise *fa = io_kiocb_to_cmd(req);
struct io_fadvise *fa = io_kiocb_to_cmd(req, struct io_fadvise);
int ret;

if (issue_flags & IO_URING_F_NONBLOCK) {
Expand Down
4 changes: 2 additions & 2 deletions io_uring/cancel.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ int io_try_cancel(struct io_uring_task *tctx, struct io_cancel_data *cd,

int io_async_cancel_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_cancel *cancel = io_kiocb_to_cmd(req);
struct io_cancel *cancel = io_kiocb_to_cmd(req, struct io_cancel);

if (unlikely(req->flags & REQ_F_BUFFER_SELECT))
return -EINVAL;
Expand Down Expand Up @@ -164,7 +164,7 @@ static int __io_async_cancel(struct io_cancel_data *cd,

int io_async_cancel(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_cancel *cancel = io_kiocb_to_cmd(req);
struct io_cancel *cancel = io_kiocb_to_cmd(req, struct io_cancel);
struct io_cancel_data cd = {
.ctx = req->ctx,
.data = cancel->addr,
Expand Down
4 changes: 2 additions & 2 deletions io_uring/epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct io_epoll {

int io_epoll_ctl_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_epoll *epoll = io_kiocb_to_cmd(req);
struct io_epoll *epoll = io_kiocb_to_cmd(req, struct io_epoll);

pr_warn_once("%s: epoll_ctl support in io_uring is deprecated and will "
"be removed in a future Linux kernel version.\n",
Expand All @@ -49,7 +49,7 @@ int io_epoll_ctl_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_epoll *ie = io_kiocb_to_cmd(req);
struct io_epoll *ie = io_kiocb_to_cmd(req, struct io_epoll);
int ret;
bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;

Expand Down
28 changes: 14 additions & 14 deletions io_uring/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct io_link {

int io_renameat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_rename *ren = io_kiocb_to_cmd(req);
struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename);
const char __user *oldf, *newf;

if (sqe->buf_index || sqe->splice_fd_in)
Expand Down Expand Up @@ -79,7 +79,7 @@ int io_renameat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_renameat(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_rename *ren = io_kiocb_to_cmd(req);
struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename);
int ret;

if (issue_flags & IO_URING_F_NONBLOCK)
Expand All @@ -95,15 +95,15 @@ int io_renameat(struct io_kiocb *req, unsigned int issue_flags)

void io_renameat_cleanup(struct io_kiocb *req)
{
struct io_rename *ren = io_kiocb_to_cmd(req);
struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename);

putname(ren->oldpath);
putname(ren->newpath);
}

int io_unlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_unlink *un = io_kiocb_to_cmd(req);
struct io_unlink *un = io_kiocb_to_cmd(req, struct io_unlink);
const char __user *fname;

if (sqe->off || sqe->len || sqe->buf_index || sqe->splice_fd_in)
Expand All @@ -128,7 +128,7 @@ int io_unlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_unlinkat(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_unlink *un = io_kiocb_to_cmd(req);
struct io_unlink *un = io_kiocb_to_cmd(req, struct io_unlink);
int ret;

if (issue_flags & IO_URING_F_NONBLOCK)
Expand All @@ -146,14 +146,14 @@ int io_unlinkat(struct io_kiocb *req, unsigned int issue_flags)

void io_unlinkat_cleanup(struct io_kiocb *req)
{
struct io_unlink *ul = io_kiocb_to_cmd(req);
struct io_unlink *ul = io_kiocb_to_cmd(req, struct io_unlink);

putname(ul->filename);
}

int io_mkdirat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_mkdir *mkd = io_kiocb_to_cmd(req);
struct io_mkdir *mkd = io_kiocb_to_cmd(req, struct io_mkdir);
const char __user *fname;

if (sqe->off || sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in)
Expand All @@ -175,7 +175,7 @@ int io_mkdirat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_mkdirat(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_mkdir *mkd = io_kiocb_to_cmd(req);
struct io_mkdir *mkd = io_kiocb_to_cmd(req, struct io_mkdir);
int ret;

if (issue_flags & IO_URING_F_NONBLOCK)
Expand All @@ -190,14 +190,14 @@ int io_mkdirat(struct io_kiocb *req, unsigned int issue_flags)

void io_mkdirat_cleanup(struct io_kiocb *req)
{
struct io_mkdir *md = io_kiocb_to_cmd(req);
struct io_mkdir *md = io_kiocb_to_cmd(req, struct io_mkdir);

putname(md->filename);
}

int io_symlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_link *sl = io_kiocb_to_cmd(req);
struct io_link *sl = io_kiocb_to_cmd(req, struct io_link);
const char __user *oldpath, *newpath;

if (sqe->len || sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in)
Expand Down Expand Up @@ -225,7 +225,7 @@ int io_symlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_symlinkat(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_link *sl = io_kiocb_to_cmd(req);
struct io_link *sl = io_kiocb_to_cmd(req, struct io_link);
int ret;

if (issue_flags & IO_URING_F_NONBLOCK)
Expand All @@ -240,7 +240,7 @@ int io_symlinkat(struct io_kiocb *req, unsigned int issue_flags)

int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_link *lnk = io_kiocb_to_cmd(req);
struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link);
const char __user *oldf, *newf;

if (sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in)
Expand Down Expand Up @@ -270,7 +270,7 @@ int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_linkat(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_link *lnk = io_kiocb_to_cmd(req);
struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link);
int ret;

if (issue_flags & IO_URING_F_NONBLOCK)
Expand All @@ -286,7 +286,7 @@ int io_linkat(struct io_kiocb *req, unsigned int issue_flags)

void io_link_cleanup(struct io_kiocb *req)
{
struct io_link *sl = io_kiocb_to_cmd(req);
struct io_link *sl = io_kiocb_to_cmd(req, struct io_link);

putname(sl->oldpath);
putname(sl->newpath);
Expand Down
3 changes: 0 additions & 3 deletions io_uring/io-wq.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,8 +624,6 @@ static int io_wqe_worker(void *data)
snprintf(buf, sizeof(buf), "iou-wrk-%d", wq->task->pid);
set_task_comm(current, buf);

audit_alloc_kernel(current);

while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) {
long ret;

Expand Down Expand Up @@ -660,7 +658,6 @@ static int io_wqe_worker(void *data)
if (test_bit(IO_WQ_BIT_EXIT, &wq->state))
io_worker_handle_work(worker);

audit_free(current);
io_worker_exit(worker);
return 0;
}
Expand Down
19 changes: 16 additions & 3 deletions io_uring/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -3885,20 +3885,24 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,

static int __init io_uring_init(void)
{
#define __BUILD_BUG_VERIFY_ELEMENT(stype, eoffset, etype, ename) do { \
#define __BUILD_BUG_VERIFY_OFFSET_SIZE(stype, eoffset, esize, ename) do { \
BUILD_BUG_ON(offsetof(stype, ename) != eoffset); \
BUILD_BUG_ON(sizeof(etype) != sizeof_field(stype, ename)); \
BUILD_BUG_ON(sizeof_field(stype, ename) != esize); \
} while (0)

#define BUILD_BUG_SQE_ELEM(eoffset, etype, ename) \
__BUILD_BUG_VERIFY_ELEMENT(struct io_uring_sqe, eoffset, etype, ename)
__BUILD_BUG_VERIFY_OFFSET_SIZE(struct io_uring_sqe, eoffset, sizeof(etype), ename)
#define BUILD_BUG_SQE_ELEM_SIZE(eoffset, esize, ename) \
__BUILD_BUG_VERIFY_OFFSET_SIZE(struct io_uring_sqe, eoffset, esize, ename)
BUILD_BUG_ON(sizeof(struct io_uring_sqe) != 64);
BUILD_BUG_SQE_ELEM(0, __u8, opcode);
BUILD_BUG_SQE_ELEM(1, __u8, flags);
BUILD_BUG_SQE_ELEM(2, __u16, ioprio);
BUILD_BUG_SQE_ELEM(4, __s32, fd);
BUILD_BUG_SQE_ELEM(8, __u64, off);
BUILD_BUG_SQE_ELEM(8, __u64, addr2);
BUILD_BUG_SQE_ELEM(8, __u32, cmd_op);
BUILD_BUG_SQE_ELEM(12, __u32, __pad1);
BUILD_BUG_SQE_ELEM(16, __u64, addr);
BUILD_BUG_SQE_ELEM(16, __u64, splice_off_in);
BUILD_BUG_SQE_ELEM(24, __u32, len);
Expand All @@ -3917,13 +3921,22 @@ static int __init io_uring_init(void)
BUILD_BUG_SQE_ELEM(28, __u32, statx_flags);
BUILD_BUG_SQE_ELEM(28, __u32, fadvise_advice);
BUILD_BUG_SQE_ELEM(28, __u32, splice_flags);
BUILD_BUG_SQE_ELEM(28, __u32, rename_flags);
BUILD_BUG_SQE_ELEM(28, __u32, unlink_flags);
BUILD_BUG_SQE_ELEM(28, __u32, hardlink_flags);
BUILD_BUG_SQE_ELEM(28, __u32, xattr_flags);
BUILD_BUG_SQE_ELEM(28, __u32, msg_ring_flags);
BUILD_BUG_SQE_ELEM(32, __u64, user_data);
BUILD_BUG_SQE_ELEM(40, __u16, buf_index);
BUILD_BUG_SQE_ELEM(40, __u16, buf_group);
BUILD_BUG_SQE_ELEM(42, __u16, personality);
BUILD_BUG_SQE_ELEM(44, __s32, splice_fd_in);
BUILD_BUG_SQE_ELEM(44, __u32, file_index);
BUILD_BUG_SQE_ELEM(44, __u16, notification_idx);
BUILD_BUG_SQE_ELEM(46, __u16, addr_len);
BUILD_BUG_SQE_ELEM(48, __u64, addr3);
BUILD_BUG_SQE_ELEM_SIZE(48, 0, cmd);
BUILD_BUG_SQE_ELEM(56, __u64, __pad2);

BUILD_BUG_ON(sizeof(struct io_uring_files_update) !=
sizeof(struct io_uring_rsrc_update));
Expand Down
10 changes: 5 additions & 5 deletions io_uring/kbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ void io_destroy_buffers(struct io_ring_ctx *ctx)

int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_provide_buf *p = io_kiocb_to_cmd(req);
struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf);
u64 tmp;

if (sqe->rw_flags || sqe->addr || sqe->len || sqe->off ||
Expand All @@ -291,7 +291,7 @@ int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_remove_buffers(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_provide_buf *p = io_kiocb_to_cmd(req);
struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf);
struct io_ring_ctx *ctx = req->ctx;
struct io_buffer_list *bl;
int ret = 0;
Expand Down Expand Up @@ -319,7 +319,7 @@ int io_remove_buffers(struct io_kiocb *req, unsigned int issue_flags)
int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
unsigned long size, tmp_check;
struct io_provide_buf *p = io_kiocb_to_cmd(req);
struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf);
u64 tmp;

if (sqe->rw_flags || sqe->splice_fd_in)
Expand Down Expand Up @@ -421,7 +421,7 @@ static int io_add_buffers(struct io_ring_ctx *ctx, struct io_provide_buf *pbuf,

int io_provide_buffers(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_provide_buf *p = io_kiocb_to_cmd(req);
struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf);
struct io_ring_ctx *ctx = req->ctx;
struct io_buffer_list *bl;
int ret = 0;
Expand All @@ -436,7 +436,7 @@ int io_provide_buffers(struct io_kiocb *req, unsigned int issue_flags)

bl = io_buffer_get_list(ctx, p->bgid);
if (unlikely(!bl)) {
bl = kzalloc(sizeof(*bl), GFP_KERNEL);
bl = kzalloc(sizeof(*bl), GFP_KERNEL_ACCOUNT);
if (!bl) {
ret = -ENOMEM;
goto err;
Expand Down
8 changes: 4 additions & 4 deletions io_uring/msg_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct io_msg {
static int io_msg_ring_data(struct io_kiocb *req)
{
struct io_ring_ctx *target_ctx = req->file->private_data;
struct io_msg *msg = io_kiocb_to_cmd(req);
struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg);

if (msg->src_fd || msg->dst_fd || msg->flags)
return -EINVAL;
Expand Down Expand Up @@ -76,7 +76,7 @@ static int io_double_lock_ctx(struct io_ring_ctx *ctx,
static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_ring_ctx *target_ctx = req->file->private_data;
struct io_msg *msg = io_kiocb_to_cmd(req);
struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg);
struct io_ring_ctx *ctx = req->ctx;
unsigned long file_ptr;
struct file *src_file;
Expand Down Expand Up @@ -122,7 +122,7 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)

int io_msg_ring_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_msg *msg = io_kiocb_to_cmd(req);
struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg);

if (unlikely(sqe->buf_index || sqe->personality))
return -EINVAL;
Expand All @@ -141,7 +141,7 @@ int io_msg_ring_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)

int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_msg *msg = io_kiocb_to_cmd(req);
struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg);
int ret;

ret = -EBADFD;
Expand Down
Loading

0 comments on commit 1da8cf9

Please sign in to comment.