summaryrefslogtreecommitdiff
path: root/net/9p
diff options
context:
space:
mode:
authorSishuai Gong <sishuai.system@gmail.com>2023-08-08 19:44:31 +0300
committerDominique Martinet <asmadeus@codewreck.org>2023-10-24 07:52:37 +0300
commit58e3ce767307130e911408c75f054d6a6673c8a3 (patch)
tree62025555aaeea9eb2b9e2725a5e7f08e9d2198d5 /net/9p
parent05d3ef8bba77c1b5f98d941d8b2d4aeab8118ef1 (diff)
downloadlinux-58e3ce767307130e911408c75f054d6a6673c8a3.tar.xz
9p/trans_fd: avoid sending req to a cancelled conn
When a connection is cancelled by p9_conn_cancel(), all requests on it should be cancelled---mark req->status as REQ_STATUS_ERROR. However, because a race over m->err between p9_conn_cancel() and p9_fd_request(), p9_fd_request might see the old value of m->err, think that the connection is NOT cancelled, and then add new requests to this cancelled connection. Fixing this issue by lock-protecting the check on m->err. Signed-off-by: Sishuai Gong <sishuai.system@gmail.com> Message-ID: <AA2DB53B-DFC7-4B88-9515-E4C9AFA6435D@gmail.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org> Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com>
Diffstat (limited to 'net/9p')
-rw-r--r--net/9p/trans_fd.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index c4015f30f9fa..f226953577b2 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -671,10 +671,14 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
m, current, &req->tc, req->tc.id);
- if (m->err < 0)
- return m->err;
spin_lock(&m->req_lock);
+
+ if (m->err < 0) {
+ spin_unlock(&m->req_lock);
+ return m->err;
+ }
+
WRITE_ONCE(req->status, REQ_STATUS_UNSENT);
list_add_tail(&req->req_list, &m->unsent_req_list);
spin_unlock(&m->req_lock);