Message ID | 20200612090833.36149-1-wanghai38@huawei.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
Series | [v2] 9p/trans_fd: Fix concurrency del of req_list in p9_fd_cancelled/p9_read_work | expand |
Wang Hai wrote on Fri, Jun 12, 2020: > p9_read_work and p9_fd_cancelled may be called concurrently. > In some cases, req->req_list may be deleted by both p9_read_work > and p9_fd_cancelled. > > We can fix it by ignoring replies associated with a cancelled > request and ignoring cancelled request if message has been received > before lock. > > Fixes: 60ff779c4abb ("9p: client: remove unused code and any reference to "cancelled" function") > Reported-by: syzbot+77a25acfa0382e06ab23@syzkaller.appspotmail.com > Signed-off-by: Wang Hai <wanghai38@huawei.com> Thanks! looks good to me, I'll queue for 5.9 as well unless you're in a hurry.
在 2020/6/12 17:10, Dominique Martinet 写道: > Wang Hai wrote on Fri, Jun 12, 2020: >> p9_read_work and p9_fd_cancelled may be called concurrently. >> In some cases, req->req_list may be deleted by both p9_read_work >> and p9_fd_cancelled. >> >> We can fix it by ignoring replies associated with a cancelled >> request and ignoring cancelled request if message has been received >> before lock. >> >> Fixes: 60ff779c4abb ("9p: client: remove unused code and any reference to "cancelled" function") >> Reported-by: syzbot+77a25acfa0382e06ab23@syzkaller.appspotmail.com >> Signed-off-by: Wang Hai <wanghai38@huawei.com> > Thanks! looks good to me, I'll queue for 5.9 as well unless you're in a > hurry. Ok, thanks.
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 13cd683a658a..3f67803123be 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -362,6 +362,10 @@ static void p9_read_work(struct work_struct *work) if (m->rreq->status == REQ_STATUS_SENT) { list_del(&m->rreq->req_list); p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD); + } else if (m->rreq->status == REQ_STATUS_FLSHD) { + /* Ignore replies associated with a cancelled request. */ + p9_debug(P9_DEBUG_TRANS, + "Ignore replies associated with a cancelled request\n"); } else { spin_unlock(&m->client->lock); p9_debug(P9_DEBUG_ERROR, @@ -703,11 +707,20 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) { p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); + spin_lock(&client->lock); + /* Ignore cancelled request if message has been received + * before lock. + */ + if (req->status == REQ_STATUS_RCVD) { + spin_unlock(&client->lock); + return 0; + } + /* we haven't received a response for oldreq, * remove it from the list. */ - spin_lock(&client->lock); list_del(&req->req_list); + req->status = REQ_STATUS_FLSHD; spin_unlock(&client->lock); p9_req_put(req);
p9_read_work and p9_fd_cancelled may be called concurrently. In some cases, req->req_list may be deleted by both p9_read_work and p9_fd_cancelled. We can fix it by ignoring replies associated with a cancelled request and ignoring cancelled request if message has been received before lock. Fixes: 60ff779c4abb ("9p: client: remove unused code and any reference to "cancelled" function") Reported-by: syzbot+77a25acfa0382e06ab23@syzkaller.appspotmail.com Signed-off-by: Wang Hai <wanghai38@huawei.com> --- v1->v2: 1. Add ignoring replies associated with a cancelled request. 2. Improved some descriptions suggested by Dominique. net/9p/trans_fd.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)