Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp5116976pxb; Mon, 28 Mar 2022 08:10:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx8HI1/FNp+vvCMN+2MJ0/pCsYkUGxOYLUU8aRfKXZalE2XxfAnuCVjISwxmkBEqTV6df77 X-Received: by 2002:a17:90a:e397:b0:1c6:3b63:bcbe with SMTP id b23-20020a17090ae39700b001c63b63bcbemr28992823pjz.180.1648480219394; Mon, 28 Mar 2022 08:10:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648480219; cv=none; d=google.com; s=arc-20160816; b=irjyJBJEAzoW62nppoa0fN09RRCBS7omeLFqyYb42I3MZQtVk84iEV4p3NMjHN2PrJ wwteYktOE0lLlxdI6K/9pW+yU2Dh+r+O72l9yquEgsRocTYUmwtWrHXqkG2jq84kmbki ayJgzgJ/s7VHfqDENW4sWSoVt9wRi5nX8xtYBe6dHu2qYNnc5Q2SaBIV7tQI3o3rEuYg 0XBd5S9xlXLUtfqon9hHtVF47RaKZfsxR5gNUNBVeZ65CMMXV6QDyv09bCp7iF2Uvov5 iguxsq56LBr2DCOtSJXgSaIIHCn7hQ9elZKaFPPyuz0Qj8oUrrbI4cTa8u0TYFQJYjpo VEXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=9RNR9zr52nHugIxJEYN2sk3uYFpuqaSTDOBoX9HzNO4=; b=j61jGNkS41jHnaUkuqK0Bol/S+OSjVw9jyiBm3YabYmPdVXE0giI4rQb928vPE5qYd pToCh9czqM9KTMC/MFW0J7Z/rvNpNAFAxCNIulCXX1ECyCtGAAKmnlnd2HBS4zROF2na zt6eXvOYArtzshPm2zbMpqcvFzSKeC6ZGjxpnx6iys8yBJSNouT/fMy7brXUYhN26gRP PaAjAA9WrJ0kUnL3gzaq2yZgIzTfzqbyfW7moP78ToPdWH+Db22mzTCwnj3e3ETjEDR3 gYMfkPrVCj0NR5RWZZloNr42Ky4qaFT10e9oAQDXu3ykquDG1/YJa++OEpG4YRnu8g16 ltdQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=PFpO6o3z; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w9-20020a170902d10900b00153b2d16478si11479983plw.128.2022.03.28.08.09.56; Mon, 28 Mar 2022 08:10:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-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=@gmail.com header.s=20210112 header.b=PFpO6o3z; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237331AbiC1BpI (ORCPT + 99 others); Sun, 27 Mar 2022 21:45:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49976 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230002AbiC1BpH (ORCPT ); Sun, 27 Mar 2022 21:45:07 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2498149699; Sun, 27 Mar 2022 18:43:27 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id c23so13562155plo.0; Sun, 27 Mar 2022 18:43:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9RNR9zr52nHugIxJEYN2sk3uYFpuqaSTDOBoX9HzNO4=; b=PFpO6o3zLKChAGfFLiBR0mChWVvul+X+MXHqw+lrP3hBGqUdcMiapDtQTy3RLzbIPb wxv+pTm73Q/VAUQmFJC44bRpW35cZigyODEmB1j6Dj/CvkDEyFwdq/Yz5EncRrySVy89 oGHQz5y/bN7eUcxmMDvGy6HfQxiasQB0UecRQQMqTbnQvZ1Bsq07cKresna+l+ECaCnj AygqzIZ5G2wxm4T+AGvFh8vAt3lJ3oWhDmt8fixqV2PJBVegjlQB9AlJ5QIyrLtEJsPP Zfx7570QAkY2k2A1E9wl+L5BnhxKL2rPis+hDcZcPlPPnGO5rOh4BwZClUQjr5lazuix U1QA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=9RNR9zr52nHugIxJEYN2sk3uYFpuqaSTDOBoX9HzNO4=; b=fB/L/Z91/E1Vf22Hxd1/CTY9/9h2Ar5D/z6KIgz9IWgYqF4cVBOowVBIMKJOp+V/cC sBd/eEmyWoCf5WEzt3A63UYA0/kTGiDyrHlh9/uu9dD1p1NTAt+W7cbJdwdxQ3vlgXLX RqEL+DWustCvzQdaRX8rk0zK5/7XZ9qLXGu2FbPhHCgqlsc62A9kYJw6aLzon0P3Nbh+ a/N5bfTYHE79tSR3i58dBE5wDHVtPoOhEBLHNjOd39jRz4LSrEHC6XqyAeQRg/hyuNIA 5R7udmdg//C0nbvCHM6PyKfAy9kTI9Chl79019c8iPXraKs+eQsTBJnl46Iq3KwMOnNt /t9Q== X-Gm-Message-State: AOAM530l57eQmuwC7AlIWrUr5p/CQEGxJ3c8fKrrBslB61nlwsVhhbB7 AgeRk7mZ2y1qUbDQmHXn92Y= X-Received: by 2002:a17:902:b10c:b0:154:a3b5:b33a with SMTP id q12-20020a170902b10c00b00154a3b5b33amr23409743plr.3.1648431806312; Sun, 27 Mar 2022 18:43:26 -0700 (PDT) Received: from ubuntu.huawei.com ([119.3.119.18]) by smtp.googlemail.com with ESMTPSA id v24-20020a634818000000b0036407db4728sm10939289pga.26.2022.03.27.18.43.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Mar 2022 18:43:25 -0700 (PDT) From: Xiaomeng Tong To: trondmy@hammerspace.com Cc: anna@kernel.org, bhalevy@panasas.com, bharrosh@panasas.com, linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, stable@vger.kernel.org, xiam0nd.tong@gmail.com Subject: Re: [PATCH] nfs: callback_proc: fix an incorrect NULL check on list iterator Date: Mon, 28 Mar 2022 09:43:14 +0800 Message-Id: <20220328014314.18987-1-xiam0nd.tong@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <436766b6fb5f3ec513629d4fa0888b77c65cfa16.camel@hammerspace.com> References: <436766b6fb5f3ec513629d4fa0888b77c65cfa16.camel@hammerspace.com> X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org On Sun, 27 Mar 2022 15:20:42 +0000, Trond Myklebust wrote: > On Sun, 2022-03-27 at 16:02 +0800, Xiaomeng Tong wrote: > > The bug is here: > > if (!server || > > server->pnfs_curr_ld->id != dev->cbd_layout_type) { > > > > The list iterator value 'server' will *always* be set and non-NULL > > by list_for_each_entry_rcu, so it is incorrect to assume that the > > iterator value will be NULL if the list is empty or no element is > > found (In fact, it will be a bogus pointer to an invalid struct > > object containing the HEAD, which is used for above check at next > > outer loop). Otherwise it may bypass the check in theory (iif > > server->pnfs_curr_ld->id == dev->cbd_layout_type, 'server' now is > > a bogus pointer) and lead to invalid memory access passing the check. > > > > To fix the bug, use a new variable 'iter' as the list iterator, > > while use the original variable 'server' as a dedicated pointer to > > point to the found element. > > > > Cc: stable@vger.kernel.org > > Fixes: 1be5683b03a76 ("pnfs: CB_NOTIFY_DEVICEID") > > Signed-off-by: Xiaomeng Tong > > --- > > fs/nfs/callback_proc.c | 9 +++++---- > > 1 file changed, 5 insertions(+), 4 deletions(-) > > > > diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c > > index c343666d9a42..84779785dc8d 100644 > > --- a/fs/nfs/callback_proc.c > > +++ b/fs/nfs/callback_proc.c > > @@ -361,7 +361,7 @@ __be32 nfs4_callback_devicenotify(void *argp, > > void *resp, > > uint32_t i; > > __be32 res = 0; > > struct nfs_client *clp = cps->clp; > > - struct nfs_server *server = NULL; > > + struct nfs_server *server = NULL, *iter; > > > > if (!clp) { > > res = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION); > > @@ -374,10 +374,11 @@ __be32 nfs4_callback_devicenotify(void *argp, > > void *resp, > > if (!server || > > server->pnfs_curr_ld->id != dev->cbd_layout_type) > > { > > rcu_read_lock(); > > - list_for_each_entry_rcu(server, &clp- > > >cl_superblocks, client_link) > > - if (server->pnfs_curr_ld && > > - server->pnfs_curr_ld->id == dev- > > >cbd_layout_type) { > > + list_for_each_entry_rcu(iter, &clp- > > >cl_superblocks, client_link) > > + if (iter->pnfs_curr_ld && > > + iter->pnfs_curr_ld->id == dev- > > >cbd_layout_type) { > > rcu_read_unlock(); > > + server = iter; > > Hmm... We're not holding any locks on the super block for 'iter' here, > so nothing is preventing it from going away while we're. > ok, i am not a 'rcu lock' expert, i will make it hold the rcu_read_lock() if necessary. > Given that we really only want a pointer to the struct > pnfs_layoutdriver_type anyway, why not just convert the code to save a > pointer to that (and do it while holding the rcu_read_lock())? > Maybe it's not that simple. If you only save a pointer to that and still use 'server' as the list iterator of list_for_each_entry_rcu, there could be problem. I.e., if no element found in list_for_each_entry_rcu in the first outer 'for' loop, and now 'server' is a bogus pointer to an invalid struct, and continue to go into the second outer 'for' loop, and the check below will lead to invalid memory access (server->pnfs_curr_ld->id), even can potentialy be bypassed with crafted data to make the condition false and mistakely run nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id); with bogus 'server'. if (!server || server->pnfs_curr_ld->id != dev->cbd_layout_type) { > The struct pnfs_layoutdriver is always expected to be a statically > allocated structure, so it won't go away as long as the pNFS driver > module remains loaded. > -- Xiaomeng Tong