Messages in this thread Patch in this message | | | From | Greg Kroah-Hartman <> | Subject | [PATCH 5.13 124/800] fuse: check connected before queueing on fpq->io | Date | Mon, 12 Jul 2021 08:02:27 +0200 |
| |
From: Miklos Szeredi <mszeredi@redhat.com>
commit 80ef08670d4c28a06a3de954bd350368780bcfef upstream.
A request could end up on the fpq->io list after fuse_abort_conn() has reset fpq->connected and aborted requests on that list:
Thread-1 Thread-2 ======== ======== ->fuse_simple_request() ->shutdown ->__fuse_request_send() ->queue_request() ->fuse_abort_conn() ->fuse_dev_do_read() ->acquire(fpq->lock) ->wait_for(fpq->lock) ->set err to all req's in fpq->io ->release(fpq->lock) ->acquire(fpq->lock) ->add req to fpq->io
After the userspace copy is done the request will be ended, but req->out.h.error will remain uninitialized. Also the copy might block despite being already aborted.
Fix both issues by not allowing the request to be queued on the fpq->io list after fuse_abort_conn() has processed this list.
Reported-by: Pradeep P V K <pragalla@codeaurora.org> Fixes: fd22d62ed0c3 ("fuse: no fc->lock for iqueue parts") Cc: <stable@vger.kernel.org> # v4.2 Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- fs/fuse/dev.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1272,6 +1272,15 @@ static ssize_t fuse_dev_do_read(struct f goto restart; } spin_lock(&fpq->lock); + /* + * Must not put request on fpq->io queue after having been shut down by + * fuse_abort_conn() + */ + if (!fpq->connected) { + req->out.h.error = err = -ECONNABORTED; + goto out_end; + + } list_add(&req->list, &fpq->io); spin_unlock(&fpq->lock); cs->req = req;
| |