On 06/11/2019 02:37, Jens Axboe wrote: > On 11/5/19 4:04 PM, Pavel Begunkov wrote: >> @@ -2475,31 +2475,30 @@ static int __io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, >> return ret; >> } >> >> -static int io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, >> - struct sqe_submit *s) >> +static int io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req) >> { >> int ret; >> >> - ret = io_req_defer(ctx, req, s->sqe); >> + ret = io_req_defer(ctx, req); >> if (ret) { >> if (ret != -EIOCBQUEUED) { >> io_free_req(req, NULL); >> - io_cqring_add_event(ctx, s->sqe->user_data, ret); >> + io_cqring_add_event(ctx, req->submit.sqe->user_data, ret); > > Cases like these are now (or can be) use-after-free. Same with this one: > Hmm, lost this in rebasing. Good catch! >> @@ -2507,12 +2506,12 @@ static int io_queue_link_head(struct io_ring_ctx *ctx, struct io_kiocb *req, >> * list. >> */ >> req->flags |= REQ_F_IO_DRAIN; >> - ret = io_req_defer(ctx, req, s->sqe); >> + ret = io_req_defer(ctx, req); >> if (ret) { >> if (ret != -EIOCBQUEUED) { >> io_free_req(req, NULL); >> __io_free_req(shadow); >> - io_cqring_add_event(ctx, s->sqe->user_data, ret); >> + io_cqring_add_event(ctx, req->submit.sqe->user_data, ret); >> return 0; > > Free the req, then deref it... > -- Pavel Begunkov