projects/linux·commit 6f2cc166

io_uring: fix possible race condition against REQ_F_NEED_CLEANUP

6f2cc166 · Xiaoguang Wang <[email protected]> · 2020-06-18 15:01:56 +08:00

In io_read() or io_write(), when io request is submitted successfully,
it'll go through the below sequence:

    kfree(iovec);
    req->flags &= ~REQ_F_NEED_CLEANUP;
    return ret;

But clearing REQ_F_NEED_CLEANUP might be unsafe. The io request may
already have been completed, and then io_complete_rw_iopoll()
and io_complete_rw() will be called, both of which will also modify
req->flags if needed. This causes a race condition, with concurrent
non-atomic modification of req->flags.

To eliminate this race, in io_read() or io_write(), if io request is
submitted successfully, we don't remove REQ_F_NEED_CLEANUP flag. If
REQ_F_NEED_CLEANUP is set, we'll leave __io_req_aux_free() to the
iovec cleanup work correspondingly.

Cc: [email protected]
Signed-off-by: Xiaoguang Wang <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Commit
6f2cc1664db20676069cff27a461ccc97dbfd114
Parents
56952e91

Changes

1 files changed · +4 −4

FileStatusAddDelContent
fs/io_uring.cmodified+4−4View file

fs/io_uring.c

View file
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 2038d52..a78201b 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -2670,8 +2670,8 @@ copy_iov:
}
}
out_free:
- kfree(iovec);
- req->flags &= ~REQ_F_NEED_CLEANUP;
+ if (!(req->flags & REQ_F_NEED_CLEANUP))
+ kfree(iovec);
return ret;
}
@@ -2793,8 +2793,8 @@ copy_iov:
}
}
out_free:
- req->flags &= ~REQ_F_NEED_CLEANUP;
- kfree(iovec);
+ if (!(req->flags & REQ_F_NEED_CLEANUP))
+ kfree(iovec);
return ret;
}