Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sishuai Gong and committed by
Dominique Martinet
58e3ce76 05d3ef8b

+6 -2
+6 -2
net/9p/trans_fd.c
··· 671 671 672 672 p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", 673 673 m, current, &req->tc, req->tc.id); 674 - if (m->err < 0) 675 - return m->err; 676 674 677 675 spin_lock(&m->req_lock); 676 + 677 + if (m->err < 0) { 678 + spin_unlock(&m->req_lock); 679 + return m->err; 680 + } 681 + 678 682 WRITE_ONCE(req->status, REQ_STATUS_UNSENT); 679 683 list_add_tail(&req->req_list, &m->unsent_req_list); 680 684 spin_unlock(&m->req_lock);