Skip to content
Snippets Groups Projects
Commit 810757a6 authored by Dominique Martinet's avatar Dominique Martinet Committed by 谢秀奇
Browse files

9p/trans_fd: abort p9_read_work if req status changed

[ Upstream commit e4ca13f7 ]

p9_read_work would try to handle an errored req even if it got put to
error state by another thread between the lookup (that worked) and the
time it had been fully read.
The request itself is safe to use because we hold a ref to it from the
lookup (for m->rreq, so it was safe to read into the request data buffer
until this point), but the req_list has been deleted at the same time
status changed, and client_cb already has been called as well, so we
should not do either.

Link: http://lkml.kernel.org/r/1539057956-23741-1-git-send-email-asmadeus@codewreck.org


Signed-off-by: default avatarDominique Martinet <dominique.martinet@cea.fr>
Reported-by: default avatar <syzbot+2222c34dc40b515f30dc@syzkaller.appspotmail.com>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 29b325f7
No related branches found
No related tags found
No related merge requests found
......@@ -292,7 +292,6 @@ static void p9_read_work(struct work_struct *work)
__poll_t n;
int err;
struct p9_conn *m;
int status = REQ_STATUS_ERROR;
m = container_of(work, struct p9_conn, rq);
......@@ -375,11 +374,17 @@ static void p9_read_work(struct work_struct *work)
p9_debug(P9_DEBUG_TRANS, "got new packet\n");
m->rreq->rc.size = m->rc.offset;
spin_lock(&m->client->lock);
if (m->rreq->status != REQ_STATUS_ERROR)
status = REQ_STATUS_RCVD;
list_del(&m->rreq->req_list);
/* update req->status while holding client->lock */
p9_client_cb(m->client, m->rreq, status);
if (m->rreq->status == REQ_STATUS_SENT) {
list_del(&m->rreq->req_list);
p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
} else {
spin_unlock(&m->client->lock);
p9_debug(P9_DEBUG_ERROR,
"Request tag %d errored out while we were reading the reply\n",
m->rc.tag);
err = -EIO;
goto error;
}
spin_unlock(&m->client->lock);
m->rc.sdata = NULL;
m->rc.offset = 0;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment