Received: by 2002:a05:6358:bb9e:b0:b9:5105:a5b4 with SMTP id df30csp1904172rwb; Sun, 4 Sep 2022 04:48:32 -0700 (PDT) X-Google-Smtp-Source: AA6agR64o8Fk6+BNQQ7fTZn97SUzAIgB/pXsqEbE62ywP+G7GG1tPVPWgTxRRIELqmqfKEwsMOuJ X-Received: by 2002:a17:907:6e9e:b0:741:56e5:67cb with SMTP id sh30-20020a1709076e9e00b0074156e567cbmr24051056ejc.256.1662292112686; Sun, 04 Sep 2022 04:48:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1662292112; cv=none; d=google.com; s=arc-20160816; b=Kyujnb90pJJjDYiqM+wQ45EteUy+2EdPPQbdu+gH8Sbs+rM7Aw69yxLkBzaOblEU2D /+gV/T6IgUFjIjRI+voUdilacSbxgDELPcqJXD5Xeadk/q5gKPYgsD+Gf2DGxnyiyVAX Rp8bDWmGsG9dB68S9sfSBSZ26oDPQzihzUeRp06vUz72F2qUE8ODRli9Oa49Dwya9bjI YqEFI/+kDmCpOvoGQLHxH74JuyI+Ng/l+ulslSIetGPxKMkRxZT0jtpdvWLB6UqveFwc Ou5WI8VQ6aD7p9vw5eCp7UfaN0+guuFZSoAvhrn/xHiVR6O9DPBD04cbjQXcdBjYyfQl +3zA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=TIX6/2ODGmdUhaznVTeEVDy0KsXHFZF3HnjlGjHKsVo=; b=dYIvRQR4vJ0C7bx6ZVH+TLeU1/teQKI5laxkP4Z07hb27D/g5vCmrXw/pYWJ+Tq7zi 7m3vqz5Cm1Q/XxwE96MAfsb5tQLoRt7vcrC1QqufiCHcFPRxk9umY8jJPezfWYjId9t6 V+zs5ntqRQ+HmoIRzbBn1C3FbMZnnmdpSNILFNDxxsYOjsC0Zl3M4FTyTUge1zn84UjA /Kp+7IyEwdKFjChU/Ty4A1aceYFd9QWdLutEJV8gtWSie3fRd7usUKgfiTXakK0ngEs0 RrWeFQvpsqz/aJTC+1KSBi1+mOD84OEO4mvZ2n69OXAL7TnPjl3Hs+BomGFTwAbUTdsg 8IsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codewreck.org header.s=2 header.b=UWhFuMRB; dkim=pass header.i=@codewreck.org header.s=2 header.b=c5LTk3So; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=codewreck.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id gb38-20020a170907962600b0073d617812b2si6783305ejc.267.2022.09.04.04.48.07; Sun, 04 Sep 2022 04:48:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@codewreck.org header.s=2 header.b=UWhFuMRB; dkim=pass header.i=@codewreck.org header.s=2 header.b=c5LTk3So; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=codewreck.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233489AbiIDL3q (ORCPT + 99 others); Sun, 4 Sep 2022 07:29:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229760AbiIDL3o (ORCPT ); Sun, 4 Sep 2022 07:29:44 -0400 Received: from nautica.notk.org (nautica.notk.org [91.121.71.147]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8473613F42 for ; Sun, 4 Sep 2022 04:29:41 -0700 (PDT) Received: by nautica.notk.org (Postfix, from userid 108) id 55280C01E; Sun, 4 Sep 2022 13:29:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codewreck.org; s=2; t=1662290979; bh=TIX6/2ODGmdUhaznVTeEVDy0KsXHFZF3HnjlGjHKsVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UWhFuMRBuIfYXNukdKvIkD9MhWXYEi89Bcx0MsF4aspuNy6cA4fUkCg+eya24n14O AqZZ9IHDURV8OdOy5gzm8NORCP0R6g5l5otEBksmRIIgIyh4RAwe5VuRqREeugk1j+ Z4oi+Oz//DapUxYLpDIj1vETo4fdAhJjMfsiSkSlK/UDCoCDU9fWhKxiTkRSXqdJhA aobfBn6kSrxORYbS1vBsgPhGFF71p6JJE737jotEa1XxmxsJUgu8+QH7zSCy9p+rJN jRI78pEZC9lq5YjCX+d6kvoghzS0xX24NrjsStzLUEypPF0ovM1YWELdRR4RkZ5YyQ zPNgAnsSyZ/qg== X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 Received: from odin.codewreck.org (localhost [127.0.0.1]) by nautica.notk.org (Postfix) with ESMTPS id 068A7C009; Sun, 4 Sep 2022 13:29:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codewreck.org; s=2; t=1662290977; bh=TIX6/2ODGmdUhaznVTeEVDy0KsXHFZF3HnjlGjHKsVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c5LTk3SoAl/YF5WMb4+StbKrkLP5gvvpiLMAUkeLSrLtCBMZ9Eq1BchCJGs5IwNq0 IHVSVq6LnMw2Jj5gP2wW3Lvj4a+buHY0dzxPWzBBBL/zVqh0eUAnlua/BZ5xYqblyA idLIhBPEQHqvmZ95xbw7xiGflc15yHLL9fNqBhby0tb7sIDR63Y2UyhVbyMzzekRsQ nwi4/jUKHZ22UAFyUUHv7THwq4Kl3kyKwV0segi7cLa+q5SpcCHcX3FkfiFqusr5dk MMKEuyxpk5ERDzd7o09LCNMvVA8tgbx8R8qbyKB5ONfjjkexuJzLrHo31iSS9ml+i+ qnan7Hj0iK6zQ== Received: from localhost (odin.codewreck.org [local]) by odin.codewreck.org (OpenSMTPD) with ESMTPA id a2d2f7aa; Sun, 4 Sep 2022 11:29:32 +0000 (UTC) From: Dominique Martinet To: v9fs-developer@lists.sourceforge.net, Tetsuo Handa Cc: syzkaller-bugs@googlegroups.com, linux_oss@crudebyte.com, linux-kernel@vger.kernel.org, Dominique Martinet , syzbot Subject: [PATCH] net/9p: use a dedicated spinlock for trans_fd Date: Sun, 4 Sep 2022 20:29:28 +0900 Message-Id: <20220904112928.1308799-1-asmadeus@codewreck.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <2470e028-9b05-2013-7198-1fdad071d999@I-love.SAKURA.ne.jp> References: <2470e028-9b05-2013-7198-1fdad071d999@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Shamelessly copying the explanation from Tetsuo Handa's suggested patch[1] (slightly reworded): syzbot is reporting inconsistent lock state in p9_req_put()[2], for p9_tag_remove() from p9_req_put() from IRQ context is using spin_lock_irqsave() on "struct p9_client"->lock but trans_fd (not from IRQ context) is using spin_lock(). Since the locks actually protect different things in client.c and in trans_fd.c, just replace trans_fd.c's lock by a new one specific to the transport instead of using spin_lock_irq* variants everywhere (client.c's protect the idr for tag allocations, while trans_fd.c's protects its own req list and request status field that acts as the transport's state machine) Link: https://lkml.kernel.org/r/2470e028-9b05-2013-7198-1fdad071d999@I-love.SAKURA.ne.jp [1] Link: https://syzkaller.appspot.com/bug?extid=2f20b523930c32c160cc [2] Reported-by: syzbot Reported-by: Tetsuo Handa Signed-off-by: Dominique Martinet --- Tetsuo Handa-san, thank you very much! I'm sorry for not respecting your opinion but it's been a pleasure to have submissions from someone on JST :) Both this and your previous patch only impact trans_fd which I can't test super easily, so while I've sent the patch here I'll only queue it to -next hopefully next week after I've had time to setup a compatible server again... net/9p/trans_fd.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index ef5760971f1e..5b4807411281 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -91,6 +91,7 @@ struct p9_poll_wait { * @mux_list: list link for mux to manage multiple connections (?) * @client: reference to client instance for this connection * @err: error state + * @req_lock: lock protecting req_list and requests statuses * @req_list: accounting for requests which have been sent * @unsent_req_list: accounting for requests that haven't been sent * @rreq: read request @@ -114,6 +115,7 @@ struct p9_conn { struct list_head mux_list; struct p9_client *client; int err; + spinlock_t req_lock; struct list_head req_list; struct list_head unsent_req_list; struct p9_req_t *rreq; @@ -189,10 +191,10 @@ static void p9_conn_cancel(struct p9_conn *m, int err) p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err); - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (m->err) { - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); return; } @@ -205,7 +207,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err) list_move(&req->req_list, &cancel_list); } - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); @@ -360,7 +362,7 @@ static void p9_read_work(struct work_struct *work) if ((m->rreq) && (m->rc.offset == m->rc.capacity)) { p9_debug(P9_DEBUG_TRANS, "got new packet\n"); m->rreq->rc.size = m->rc.offset; - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (m->rreq->status == REQ_STATUS_SENT) { list_del(&m->rreq->req_list); p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD); @@ -369,14 +371,14 @@ static void p9_read_work(struct work_struct *work) p9_debug(P9_DEBUG_TRANS, "Ignore replies associated with a cancelled request\n"); } else { - spin_unlock(&m->client->lock); + spin_unlock(&m->req_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); + spin_unlock(&m->req_lock); m->rc.sdata = NULL; m->rc.offset = 0; m->rc.capacity = 0; @@ -454,10 +456,10 @@ static void p9_write_work(struct work_struct *work) } if (!m->wsize) { - spin_lock(&m->client->lock); + spin_lock(&m->req_lock); if (list_empty(&m->unsent_req_list)) { clear_bit(Wworksched, &m->wsched); - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); return; } @@ -472,7 +474,7 @@ static void p9_write_work(struct work_struct *work) m->wpos = 0; p9_req_get(req); m->wreq = req; - spin_unlock(&m->client->lock); + spin_unlock(&m->req_lock); } p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n", @@ -670,10 +672,10 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) if (m->err < 0) return m->err; - spin_lock(&client->lock); + spin_lock(&m->req_lock); req->status = REQ_STATUS_UNSENT; list_add_tail(&req->req_list, &m->unsent_req_list); - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); if (test_and_clear_bit(Wpending, &m->wsched)) n = EPOLLOUT; @@ -688,11 +690,13 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) { + struct p9_trans_fd *ts = client->trans; + struct p9_conn *m = &ts->conn; int ret = 1; p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); - spin_lock(&client->lock); + spin_lock(&m->req_lock); if (req->status == REQ_STATUS_UNSENT) { list_del(&req->req_list); @@ -700,21 +704,24 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) p9_req_put(client, req); ret = 0; } - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); return ret; } static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) { + struct p9_trans_fd *ts = client->trans; + struct p9_conn *m = &ts->conn; + p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); - spin_lock(&client->lock); + spin_lock(&m->req_lock); /* Ignore cancelled request if message has been received * before lock. */ if (req->status == REQ_STATUS_RCVD) { - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); return 0; } @@ -723,7 +730,8 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) */ list_del(&req->req_list); req->status = REQ_STATUS_FLSHD; - spin_unlock(&client->lock); + spin_unlock(&m->req_lock); + p9_req_put(client, req); return 0; @@ -832,6 +840,7 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd) client->trans = ts; client->status = Connected; + spin_lock_init(&ts->conn.req_lock); return 0; @@ -866,6 +875,7 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket) p->wr = p->rd = file; client->trans = p; client->status = Connected; + spin_lock_init(&p->conn.req_lock); p->rd->f_flags |= O_NONBLOCK; -- 2.35.1