mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
io_uring: Fix XArray usage in io_uring_add_task_file
The xas_store() wasn't paired with an xas_nomem() loop, so if it couldn't allocate memory using GFP_NOWAIT, it would leak the reference to the file descriptor. Also the node pointed to by the xas could be freed between the call to xas_load() under the rcu_read_lock() and the acquisition of the xa_lock. It's easier to just use the normal xa_load/xa_store interface here. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> [axboe: fix missing assign after alloc, cur_uring -> tctx rename] Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
ce765372bc
commit
236434c343
@ -8586,27 +8586,24 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx,
|
||||
*/
|
||||
static int io_uring_add_task_file(struct file *file)
|
||||
{
|
||||
if (unlikely(!current->io_uring)) {
|
||||
struct io_uring_task *tctx = current->io_uring;
|
||||
|
||||
if (unlikely(!tctx)) {
|
||||
int ret;
|
||||
|
||||
ret = io_uring_alloc_task_context(current);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
tctx = current->io_uring;
|
||||
}
|
||||
if (current->io_uring->last != file) {
|
||||
XA_STATE(xas, ¤t->io_uring->xa, (unsigned long) file);
|
||||
void *old;
|
||||
if (tctx->last != file) {
|
||||
void *old = xa_load(&tctx->xa, (unsigned long)file);
|
||||
|
||||
rcu_read_lock();
|
||||
old = xas_load(&xas);
|
||||
if (old != file) {
|
||||
if (!old) {
|
||||
get_file(file);
|
||||
xas_lock(&xas);
|
||||
xas_store(&xas, file);
|
||||
xas_unlock(&xas);
|
||||
xa_store(&tctx->xa, (unsigned long)file, file, GFP_KERNEL);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
current->io_uring->last = file;
|
||||
tctx->last = file;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user