mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
fuse-uring: remove request-less entries from ent_w_req_queue to fix NULL deref
If a copy into the userspace ring buffer fails, a request will be
terminated and fuse_uring_req_end() will set ent->fuse_req to NULL but
it will leave the entry on ent_w_req_queue in FRRS_FUSE_REQ state. This
can lead to a NULL deref if the request expiration logic scans
ent_w_req_queue in the window before the entry is moved off it.
Fix this by taking the entry off ent_w_req_queue and changing its state
from FRRS_FUSE_REQ to FRRS_INVALID before terminating the request.
Fixes: 4fea593e62 ("fuse: optimize over-io-uring request expiration check")
Cc: stable@kernel.org
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
f8fce75fed
commit
1c57a69be9
|
|
@ -709,10 +709,20 @@ static int fuse_uring_prepare_send(struct fuse_ring_ent *ent,
|
|||
int err;
|
||||
|
||||
err = fuse_uring_copy_to_ring(ent, req);
|
||||
if (!err)
|
||||
if (!err) {
|
||||
set_bit(FR_SENT, &req->flags);
|
||||
else
|
||||
} else {
|
||||
/*
|
||||
* Copying the request failed. Remove the entry from the
|
||||
* ent_w_req_queue list and terminate the request
|
||||
*/
|
||||
spin_lock(&ent->queue->lock);
|
||||
list_del_init(&ent->list);
|
||||
ent->state = FRRS_INVALID;
|
||||
spin_unlock(&ent->queue->lock);
|
||||
|
||||
fuse_uring_req_end(ent, req, err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user