io_uring: io_wq_submit_work() should not touch req->rw
Jens Axboe
maintainerPATCH 1/1 io_uring: io_wq_submit_work() should not touch req->rw
I've been chasing a weird and obscure crash that was userspace stack corruption, and finally narrowed it down to a bit flip that made a stack address invalid. io_wq_submit_work() unconditionally flips the req->rw.ki_flags IOCB_NOWAIT bit, but since it's a generic work handler, this isn't valid. Normal read/write operations own that part of the request, on other types it could be something else.
Move the IOCB_NOWAIT clear to the read/write handlers where it belongs.
Signed-off-by Jens Axboe <[email protected]>
---
This one was fun to find, random flip of a bit in an unrelated struct...
fs/io_uring.c +8 -3
@@ -1817,6 +1817,10 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,return ret; } +/* Ensure we clear previously set non-block flag */ +if (!force_nonblock) + req->rw.ki_flags &= ~IOCB_NOWAIT ; + file = req->file; io_size = ret;if (req->flags &REQ_F_LINK )
@@ -1906,6 +1910,10 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,return ret; } +/* Ensure we clear previously set non-block flag */ +if (!force_nonblock) + req->rw.ki_flags &= ~IOCB_NOWAIT ; + file = kiocb->ki_filp; io_size = ret;if (req->flags &REQ_F_LINK )
@@ -3272,9 +3280,6 @@ static void io_wq_submit_work(struct io_wq_work **workptr)struct io_kiocb *nxt =NULL ;int ret =0 ; -/* Ensure we clear previously set non-block flag */ - req->rw.ki_flags &= ~IOCB_NOWAIT ; -if (work->flags &IO_WQ_WORK_CANCEL ) ret = -ECANCELED ;
Signature · 1 line
Jens Axboe