From patchwork Sun Feb 4 02:17:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544419 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ACBBC6FA8; Sun, 4 Feb 2024 02:17:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=mCkDyvVh3RmGzDwoVrJzY0dWQ678j9YRE/LTuqWysCDw6flnnu8rJb+LyfTV5YkoL8K/WZSBiFIh06UHotNJn3El71bkyU9nF6W97CeMMeUa42zePgI+yNebWAhiK1Yabzc+ydM7glJ2uLK20xpvoa2R2y35HTvXj2g+yX9V2lk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=j6rsvNN8oo5Bvj0EJ/yVmFHfs8Um7QkVVzBq0K42Rqw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cPgtVnBcKCWxjXzi7+XVXHH0zFHCgwZ+zZKo749MYFARMsaH2v/qnNpx4PCaCQ50yS1KZflORTm8Eg9ahQvuxVTW0VU1xYBIwI89aVhj5p5N+ig5oTtviOnxt1Vg8NXrH9mB+0cIcojiOaMGn7766pRFg/OPDElmY0cFCWv34pQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=BfiaI6RP; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="BfiaI6RP" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=1HFI4KKL79Sd/NlR6QYbK/LO3YNDNZj8ruRJ2Po8n78=; b=BfiaI6RPnXysexAqLOvzi/xd4/ xNQPKqHFXPKgXHMATcWLBhPpjAX2hBrdsZ4f2kv8pFN9qnEXeVAY/T/0zHISphhPHGp983TaopYhX JiEhRug4uAeivhZ62q8RBH8BwurRmaVlNA1rrxGt8VaXyN1F6MeVAYVwVaU2/Ficj/n1MLKSqBm8K koW3ZUCW855MWUF1bfbFJBFasSiwUaGxg4mXy5aTcN9Woh5mqF0sOTyPKg3TEC3/QJx4HsDKAe90F Tp1hdtHYVWhp05Uq7XiM2VqM0KEfl6fQwDbgJmGRk5d0g0ZKc2lEjYLtjlvY+eZSGgv/puzMo0UXt NvAu0mpw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4h-004rCn-2m; Sun, 04 Feb 2024 02:17:40 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 01/13] fs/super.c: don't drop ->s_user_ns until we free struct super_block itself Date: Sun, 4 Feb 2024 02:17:27 +0000 Message-Id: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021436.GH2087318@ZenIV> References: <20240204021436.GH2087318@ZenIV> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro Avoids fun races in RCU pathwalk... Same goes for freeing LSM shite hanging off super_block's arse. Signed-off-by: Al Viro Reviewed-by: Christian Brauner Reviewed-by: Jeff Layton --- fs/super.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/fs/super.c b/fs/super.c index d35e85295489..d6efeba0d0ce 100644 --- a/fs/super.c +++ b/fs/super.c @@ -274,9 +274,10 @@ static void destroy_super_work(struct work_struct *work) { struct super_block *s = container_of(work, struct super_block, destroy_work); - int i; - - for (i = 0; i < SB_FREEZE_LEVELS; i++) + security_sb_free(s); + put_user_ns(s->s_user_ns); + kfree(s->s_subtype); + for (int i = 0; i < SB_FREEZE_LEVELS; i++) percpu_free_rwsem(&s->s_writers.rw_sem[i]); kfree(s); } @@ -296,9 +297,6 @@ static void destroy_unused_super(struct super_block *s) super_unlock_excl(s); list_lru_destroy(&s->s_dentry_lru); list_lru_destroy(&s->s_inode_lru); - security_sb_free(s); - put_user_ns(s->s_user_ns); - kfree(s->s_subtype); shrinker_free(s->s_shrink); /* no delays needed */ destroy_super_work(&s->destroy_work); @@ -409,9 +407,6 @@ static void __put_super(struct super_block *s) WARN_ON(s->s_dentry_lru.node); WARN_ON(s->s_inode_lru.node); WARN_ON(!list_empty(&s->s_mounts)); - security_sb_free(s); - put_user_ns(s->s_user_ns); - kfree(s->s_subtype); call_rcu(&s->rcu, destroy_super_rcu); } } From patchwork Sun Feb 4 02:17:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544418 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF2916FC5; Sun, 4 Feb 2024 02:17:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=BOgqL7YbO7aAqSDpdIwJkxsWqYUzlqGYrqq79sNVruofc8l6bCaAWnaPO7uf9dlLdtvMpYdJ90pGFuAtOeApsAEQQv2vNXnrx9s+Mi/iYFEbjw56UkZTlDUAE11fXy+MW39PYuI+ih7kS/e4XJ82pi7d1a+rzde6c5uPon/0bQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=v5nm9WdCUwUgJfQ97cmtXjLDq45y1UqLvQaZ0A5z2ZY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mcOxfLIfb2dkG+Y5phLajGHnPekorfz+l78YgV2ViDcvRGz0UBcv9AaHl94c9TeVShT9uIa27pCVAFS07C4MPSX9KgolojM6pbuteDGa7ZtaK8sWUX87XTnefrUcn+syAKAOgYsLeVeoBx7vSmy3ideWTou9dlXIlIMLlL2Mxqk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=LGcxzo4I; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="LGcxzo4I" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=WNs3vukbXJtl12Oxlgybl8Hl88cxUtaVDUYMxN0ihgM=; b=LGcxzo4IlqtZEUOa+v0SpEXnZ2 DQTG2ASGJxbT8A1OnFm4F9VWP9wkAiedcZhFYqXPzd5TMBUJ4k4H1KScdcc1Os45IRjg3QN0b+7FK fyLWpO/DTbglgPM8gcpubs7ZL9gghTV4JoaRg37REEWWmhLGJl8CZeFzNsKHrA73MUu0vvzMgBWMe ++e7gAMZ/ItTOzFUpw83GE7onAOlJGzWnsfVFuyA03K8I2Bo6kidvJ1ohmTwruTuvISmmg/52K6bT ZS88i3QMl+eKMct5NUDkCCeMZeXlhWn2TXNe1BMXcFSLLwoB9iHlUZmnk6FNzzqzDlUoAIZLS6eXL QHGwd72g==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4i-004rCp-0J; Sun, 04 Feb 2024 02:17:40 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 02/13] rcu pathwalk: prevent bogus hard errors from may_lookup() Date: Sun, 4 Feb 2024 02:17:28 +0000 Message-Id: <20240204021739.1157830-2-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro If lazy call of ->permission() returns a hard error, check that try_to_unlazy() succeeds before returning it. That both makes life easier for ->permission() instances and closes the race in ENOTDIR handling - it is possible that positive d_can_lookup() seen in link_path_walk() applies to the state *after* unlink() + mkdir(), while nd->inode matches the state prior to that. Normally seeing e.g. EACCES from permission check in rcu pathwalk means that with some timings non-rcu pathwalk would've run into the same; however, running into a non-executable regular file in the middle of a pathname would not get to permission check - it would fail with ENOTDIR instead. Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/namei.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 4e0de939fea1..9342fa6a38c2 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1717,7 +1717,11 @@ static inline int may_lookup(struct mnt_idmap *idmap, { if (nd->flags & LOOKUP_RCU) { int err = inode_permission(idmap, nd->inode, MAY_EXEC|MAY_NOT_BLOCK); - if (err != -ECHILD || !try_to_unlazy(nd)) + if (!err) // success, keep going + return 0; + if (!try_to_unlazy(nd)) + return -ECHILD; // redo it all non-lazy + if (err != -ECHILD) // hard error return err; } return inode_permission(idmap, nd->inode, MAY_EXEC); From patchwork Sun Feb 4 02:17:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544414 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2EB0D6FDC; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=QuQVn7JhECpnVputqqzF192n8N7hqDCPbXEZFmLhGkpebKFfwy0i1Pms26/Oc2g1F+GY04zkW2Z4+ZatbHV9MklwNAP82Z9w5J+1sW1AFWC0v6u2ydMQK2YBR0ietuuTRkvbOejoWooXwkI6AzfkzdRcPNXA6qa7yiDBxQhhq5Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=5PEjSfqBc+iRYNChNww87Qinyt2iIPQDllUAPWBttFg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KYMtZ9inaDDl3bBmfm6BIcpyq52ZKjs5llhSjELjLRVdVtBr8mwbeSO8r+b4xrSSJuvycfcC/389VcWItVVIVbfW9fGyWNGeBhwT8uPqjiDgd2u6ZgGpAqHng8tlsc7dTFHDrbx0D7KbzB87HY2Pg+WrJtIjHWexqDlgEWPWv3Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=Br94/XyO; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="Br94/XyO" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=Ug2Y34xz5+mbpB8ClVi23teq0mMkMZtGfWZr82RpmBQ=; b=Br94/XyOhQiWIXAAuSQKmxkqqO /vVYbOvlfvO+Jva/uJh+scC9a9TYI95TAb0K+29rPGnQ5TktMkTxLipLaFrVwlKZLfVAM70wzGpkQ ZmuBfZlBiBG6+A0S941L7vFGj80X3ZseYCrOjt3lIUgJxDtY52bUdKORzENqsdoX6kld2NYpVgyRl Wk6HrwTlb9sOWRaytkOPeRtwW1185UuBE+KYxzTEkZmgLZyIJrpr9tWqJgcMkYoJItePUdAu+BCQJ TH2EhCPIK0U1ugJ0MTelBO1oPeMaIEMqsJt2F1gQuKWQWHSRv5VItYqY8gizscfW42jNkWPtqAuJp ZWQfaGHQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4i-004rCt-0y; Sun, 04 Feb 2024 02:17:40 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 03/13] affs: free affs_sb_info with kfree_rcu() Date: Sun, 4 Feb 2024 02:17:29 +0000 Message-Id: <20240204021739.1157830-3-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro one of the flags in it is used by ->d_hash()/->d_compare() Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/affs/affs.h | 1 + fs/affs/super.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 60685ec76d98..2e612834329a 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h @@ -105,6 +105,7 @@ struct affs_sb_info { int work_queued; /* non-zero delayed work is queued */ struct delayed_work sb_work; /* superblock flush delayed work */ spinlock_t work_lock; /* protects sb_work and work_queued */ + struct rcu_head rcu; }; #define AFFS_MOUNT_SF_INTL 0x0001 /* International filesystem. */ diff --git a/fs/affs/super.c b/fs/affs/super.c index 58b391446ae1..b56a95cf414a 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -640,7 +640,7 @@ static void affs_kill_sb(struct super_block *sb) affs_brelse(sbi->s_root_bh); kfree(sbi->s_prefix); mutex_destroy(&sbi->s_bmlock); - kfree(sbi); + kfree_rcu(sbi, rcu); } } From patchwork Sun Feb 4 02:17:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544415 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2EADB6FD1; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=LF6kvzr60KqxMrcQE+PygXnMIIca83KnwyLeG5wlfOLMqrdgJ12KwJuV4inSW6E9tpky9x/4PWqruZF2fEEjqsScCa7RkjpZcT0tsKNDS2LGIP/+b4ebfCljYCj+5yw1o89+KFNbSPjxeCwqrelXdUlmRBLsd5OGuxzWbcU6msw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=1rtYk8nQaR6Z1oX3dIJL6BYRNYvWov9U8Si234YvJHY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZECjwoPZ4FdUv4C/yBe8H524OzCiriAUaTHhndKA9hpl4kHDao9I4LW/gWG5FFU7ZKuzfWUKWJ5+8OYV0TqNkzPRTgJM/B96AcL/n89rvNAwsZ2SJn6EUvGkUYJcJJbbdkHvvPiYxPFNkA6tga0w+myaNmUDSx+o3mhc7m08JGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=TtcHfJzG; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="TtcHfJzG" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=txbefR1bImZynMySniqB43HTfyckqDaK6LKKZ+70ogY=; b=TtcHfJzGmY3hgu42vlk+4hxcrn aGH28IkeY0tk962KTYy2Vtmq5rrH3ZClMikX9dt8cn7iMPHvyYDMYuXkvBQotov6cELYdKdqBO+E+ Yen++U2pB6iPd8HbYiTl5zAYfb8hq669w7GcE01+aWKUOt3SjKnNa/MX/7rV+DTbrUtxduPKPckyy FyiOpRK40a3l+Q4sJRMYwO+o1+YL1K8x4Fa/gy6py3TTjHc5ctEoutuxSOkUNciQxpA1ProNsNSaL L4cV3zTg+tODNaIUdLWEk1D2UQgT+UQMEBJnLHbSHX23dlkMJ1LxW4wCLMw6qc1zQDuD6owQcEIMN x+jhbwEw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4i-004rCx-1g; Sun, 04 Feb 2024 02:17:40 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 04/13] exfat: move freeing sbi, upcase table and dropping nls into rcu-delayed helper Date: Sun, 4 Feb 2024 02:17:30 +0000 Message-Id: <20240204021739.1157830-4-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro That stuff can be accessed by ->d_hash()/->d_compare(); as it is, we have a hard-to-hit UAF if rcu pathwalk manages to get into ->d_hash() on a filesystem that is in process of getting shut down. Besides, having nls and upcase table cleanup moved from ->put_super() towards the place where sbi is freed makes for simpler failure exits. Signed-off-by: Al Viro Acked-by: Christian Brauner --- fs/exfat/exfat_fs.h | 1 + fs/exfat/nls.c | 14 ++++---------- fs/exfat/super.c | 20 +++++++++++--------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 9474cd50da6d..361595433480 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -275,6 +275,7 @@ struct exfat_sb_info { spinlock_t inode_hash_lock; struct hlist_head inode_hashtable[EXFAT_HASH_SIZE]; + struct rcu_head rcu; }; #define EXFAT_CACHE_VALID 0 diff --git a/fs/exfat/nls.c b/fs/exfat/nls.c index 705710f93e2d..afdf13c34ff5 100644 --- a/fs/exfat/nls.c +++ b/fs/exfat/nls.c @@ -655,7 +655,6 @@ static int exfat_load_upcase_table(struct super_block *sb, unsigned int sect_size = sb->s_blocksize; unsigned int i, index = 0; u32 chksum = 0; - int ret; unsigned char skip = false; unsigned short *upcase_table; @@ -673,8 +672,7 @@ static int exfat_load_upcase_table(struct super_block *sb, if (!bh) { exfat_err(sb, "failed to read sector(0x%llx)", (unsigned long long)sector); - ret = -EIO; - goto free_table; + return -EIO; } sector++; for (i = 0; i < sect_size && index <= 0xFFFF; i += 2) { @@ -701,15 +699,12 @@ static int exfat_load_upcase_table(struct super_block *sb, exfat_err(sb, "failed to load upcase table (idx : 0x%08x, chksum : 0x%08x, utbl_chksum : 0x%08x)", index, chksum, utbl_checksum); - ret = -EINVAL; -free_table: - exfat_free_upcase_table(sbi); - return ret; + return -EINVAL; } static int exfat_load_default_upcase_table(struct super_block *sb) { - int i, ret = -EIO; + int i; struct exfat_sb_info *sbi = EXFAT_SB(sb); unsigned char skip = false; unsigned short uni = 0, *upcase_table; @@ -740,8 +735,7 @@ static int exfat_load_default_upcase_table(struct super_block *sb) return 0; /* FATAL error: default upcase table has error */ - exfat_free_upcase_table(sbi); - return ret; + return -EIO; } int exfat_create_upcase_table(struct super_block *sb) diff --git a/fs/exfat/super.c b/fs/exfat/super.c index d9d4fa91010b..fcb658267765 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -39,9 +39,6 @@ static void exfat_put_super(struct super_block *sb) exfat_free_bitmap(sbi); brelse(sbi->boot_bh); mutex_unlock(&sbi->s_lock); - - unload_nls(sbi->nls_io); - exfat_free_upcase_table(sbi); } static int exfat_sync_fs(struct super_block *sb, int wait) @@ -600,7 +597,7 @@ static int __exfat_fill_super(struct super_block *sb) ret = exfat_load_bitmap(sb); if (ret) { exfat_err(sb, "failed to load alloc-bitmap"); - goto free_upcase_table; + goto free_bh; } ret = exfat_count_used_clusters(sb, &sbi->used_clusters); @@ -613,8 +610,6 @@ static int __exfat_fill_super(struct super_block *sb) free_alloc_bitmap: exfat_free_bitmap(sbi); -free_upcase_table: - exfat_free_upcase_table(sbi); free_bh: brelse(sbi->boot_bh); return ret; @@ -701,12 +696,10 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_root = NULL; free_table: - exfat_free_upcase_table(sbi); exfat_free_bitmap(sbi); brelse(sbi->boot_bh); check_nls_io: - unload_nls(sbi->nls_io); return err; } @@ -771,13 +764,22 @@ static int exfat_init_fs_context(struct fs_context *fc) return 0; } +static void delayed_free(struct rcu_head *p) +{ + struct exfat_sb_info *sbi = container_of(p, struct exfat_sb_info, rcu); + + unload_nls(sbi->nls_io); + exfat_free_upcase_table(sbi); + exfat_free_sbi(sbi); +} + static void exfat_kill_sb(struct super_block *sb) { struct exfat_sb_info *sbi = sb->s_fs_info; kill_block_super(sb); if (sbi) - exfat_free_sbi(sbi); + call_rcu(&sbi->rcu, delayed_free); } static struct file_system_type exfat_fs_type = { From patchwork Sun Feb 4 02:17:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544420 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B4D47460; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=tcLqQ+Y2qvtnPMrN1vGcukvnFqYb5cZdu1Rt63mpJI4p8Mxp4J7x1Hd3JM91QCi8XleDmm99IA2DKJOELLRNgE87QVb3EbnYokhTHclnBpksVJmv9jTJEKtf17ZlqtZNDudkBnSYIzUE0PLbqRZMP6vRvmpd8rYvfg161kNTqgs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=sG42Zf5DTiNNOcAGlM3Zr/H2o4OoCoJx8NrtZkRtutU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aK5h7M0WyGTbKtTPJlaKi2diYtQC5Ty72zarF9tS+o8NeNyav+FG5xq9U0MgRUIMWhvE0U0WiRqlhY1Cg33m4hP0WOhw427JTcki9vP3mo4XMTPt0qYy/nsfXohwCH+8KiBse21q0kD8Hm+z4jS4p93m0Ae4Ra9FdJtvnlsJjR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=qxbrWosc; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="qxbrWosc" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=EjWkAFYMC0New8r7aI9BMXvNYwHQVwhCzm32GsCIcMM=; b=qxbrWoscao3BKYzdD4PD0fuDnE UqP/FXLwX6jwmPbGH2l3okPgOnMkOvN4mfB2xIe3CBE66vbg4tcyGehDknGgRcBnzWVYAW9Lg8lVq WVina8FjERTRoggaxszJIc4HAQ9rlrJRXvyuw/HlXZ22ksVm5olRNKwf3xv0uJiKF9sbAoRapGU0k 6pyhPYetdWWbFzrocj9H5kQ/F2sJK8oHTQCFJZvodGoXar0hHTveIw5gYjefjHKtH+BMyuFF5aWAi Nyc4n7zXFjKgC28keu+RISSYHcrJL6Aw9O04dAx9sLqRm4/8q1iHdse2CmN8CIT7esZk4ENubZV2O m1XMfxRw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4i-004rD1-2B; Sun, 04 Feb 2024 02:17:40 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 05/13] hfsplus: switch to rcu-delayed unloading of nls and freeing ->s_fs_info Date: Sun, 4 Feb 2024 02:17:31 +0000 Message-Id: <20240204021739.1157830-5-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro ->d_hash() and ->d_compare() use those, so we need to delay freeing them. Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/hfsplus/hfsplus_fs.h | 1 + fs/hfsplus/super.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 7ededcb720c1..012a3d003fbe 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -190,6 +190,7 @@ struct hfsplus_sb_info { int work_queued; /* non-zero delayed work is queued */ struct delayed_work sync_work; /* FS sync delayed work */ spinlock_t work_lock; /* protects sync_work and work_queued */ + struct rcu_head rcu; }; #define HFSPLUS_SB_WRITEBACKUP 0 diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 1986b4f18a90..97920202790f 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -277,6 +277,14 @@ void hfsplus_mark_mdb_dirty(struct super_block *sb) spin_unlock(&sbi->work_lock); } +static void delayed_free(struct rcu_head *p) +{ + struct hfsplus_sb_info *sbi = container_of(p, struct hfsplus_sb_info, rcu); + + unload_nls(sbi->nls); + kfree(sbi); +} + static void hfsplus_put_super(struct super_block *sb) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); @@ -302,9 +310,7 @@ static void hfsplus_put_super(struct super_block *sb) hfs_btree_close(sbi->ext_tree); kfree(sbi->s_vhdr_buf); kfree(sbi->s_backup_vhdr_buf); - unload_nls(sbi->nls); - kfree(sb->s_fs_info); - sb->s_fs_info = NULL; + call_rcu(&sbi->rcu, delayed_free); } static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf) From patchwork Sun Feb 4 02:17:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544422 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7BE687465; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=afYSAHHO2rRYLUVomqjPgGO3voo2d5qzoFHlBu2AcTu5lvH5oQXcD0YwcilP3KrYKgIZ/wc/jfvepfLanzpTeb2PIBmiA8VFDCcjvDDeuIdWEK3M7cwZBxInsUIqJyKEmHqucoEIvBcmj18sPOBHKwNsPG1DrL2ccRCaTjsGXpQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=0//Yu6BXY3luoPRYjvD5gzNg1J5nlPcjVRvQVUP3aW8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dr6HbuDCz7MXPU4PNSv+OYkCmM9rxUlBq0johq1yIZn0FEXGcpW43ELd+gHHg6o2yZ0ChxTyKbzHEpxQxNkrrHqd+dTM4Uu4KxRhr9LVpGZHAh9MdWwnUOaherzZhQVelnJCaEXT5ddkOWP2z9/yx0F4xLOFCbeqfE9RjqAL9A8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=HJi2F5da; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="HJi2F5da" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=J2wtRa+Q8aO9z7aGDBhoVjKdvq+lyz4asnShgUjCJxA=; b=HJi2F5da1qO426GyqZHAWdJud3 aDX1RoDxS01RdSvbtmsHDSOOcbPlobtlbFRajMenNsnH76opM7kXswiqn92ehF0Vi+9LEFjVYm+MM xRxtBkFNlMg/X0t+Dqna/nwVQcK8PPu4VDtRCElKd+iBeZOmDMwGmHEePmFRUm6RbLM2tkg3rN+7B oUUOP8e8kZZ8FQGyM7mHEU1MPurxMbMS1XlFXywykqn4mlF8niNvOLVqxJT1RzvBoGPnwPmoP/Qq1 jZIhL55DIyrCXlRTFKkPc+KcH35hSpRmS9zUIIcfZB5AhjxctY27ehIXAKGOGJ0c3bIbu8fDfNa+G L3czJNdw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4i-004rD5-2c; Sun, 04 Feb 2024 02:17:40 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 06/13] afs: fix __afs_break_callback() / afs_drop_open_mmap() race Date: Sun, 4 Feb 2024 02:17:32 +0000 Message-Id: <20240204021739.1157830-6-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro In __afs_break_callback() we might check ->cb_nr_mmap and if it's non-zero do queue_work(&vnode->cb_work). In afs_drop_open_mmap() we decrement ->cb_nr_mmap and do flush_work(&vnode->cb_work) if it reaches zero. The trouble is, there's nothing to prevent __afs_break_callback() from seeing ->cb_nr_mmap before the decrement and do queue_work() after both the decrement and flush_work(). If that happens, we might be in trouble - vnode might get freed before the queued work runs. __afs_break_callback() is always done under ->cb_lock, so let's make sure that ->cb_nr_mmap can change from non-zero to zero while holding ->cb_lock (the spinlock component of it - it's a seqlock and we don't need to mess with the counter). Signed-off-by: Al Viro Acked-by: Christian Brauner --- fs/afs/file.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/afs/file.c b/fs/afs/file.c index 3d33b221d9ca..ef2cc8f565d2 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -417,13 +417,17 @@ static void afs_add_open_mmap(struct afs_vnode *vnode) static void afs_drop_open_mmap(struct afs_vnode *vnode) { - if (!atomic_dec_and_test(&vnode->cb_nr_mmap)) + if (atomic_add_unless(&vnode->cb_nr_mmap, -1, 1)) return; down_write(&vnode->volume->open_mmaps_lock); - if (atomic_read(&vnode->cb_nr_mmap) == 0) + read_seqlock_excl(&vnode->cb_lock); + // the only place where ->cb_nr_mmap may hit 0 + // see __afs_break_callback() for the other side... + if (atomic_dec_and_test(&vnode->cb_nr_mmap)) list_del_init(&vnode->cb_mmap_link); + read_sequnlock_excl(&vnode->cb_lock); up_write(&vnode->volume->open_mmaps_lock); flush_work(&vnode->cb_work); From patchwork Sun Feb 4 02:17:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544416 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF2B77475; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=jVjWJuo1nZ5qTdTTi7kVRp/w0fD4TsHEDmTDI0NYDtoU4vSQhoXg2ExW465Fp/JEbxhiBjKJlcUSNcrbh7T7IVMTXlmoOhPzkiDCuTiqaJhMlcP6f+v6DDdJeuZ6VTm8v2ruMYr1fg7sO5Uic/me+lO9YJ5EEKrJpC1dmm7N0Gc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=ESeuy+sRmSqcgc4J62uxsN9xRpufWmLKZ9Z0jimpwkU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=MM2sJ1Gf1jTsPCvc+VI8X1drcQCuxNHSOiN1EDUaoUUbtWYiYOjEy//2D4Z2Wn1PyMUkpCNyYxN5RS78N+HKCz5hLOeohxPDrRYmZ0DI59m0nlmGsF+JCHhVSuBX0ZorhIi+2tSYP7ZLbMi2Y7sKT19nEzjkmdWKcYWFEVcA0Ew= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=Tgjp9rq2; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="Tgjp9rq2" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=MbX9tJudD6m9OahDFqTMdqQPpdHnN+yBPYQKKXuKt8M=; b=Tgjp9rq27MqRdktDJN+34uxz1K BFCAjAJYerA2pn/+4DZkb5qCDauknX80pKN47HZs1vz0zmBshCvTYpox0FhExQ8LNFTa+M0iOl18+ zWugqvaVdQHUPcLEFvXLhuu4TD15YU1LX+zEVR7c6vNugP16y9YbYYhZsQBP2e4SWigXVZ41eyJP8 8iNn8S2C2dzWFy5aLECafk4BaK5szIX2/t537N6Ch3UEhkb+GrbUVboKmTW3EKyZHwGbcTqKlW7Fr 1GTt0w5k2m9RXKLsh7+4tNELpU5Lx963XKuVGEhOXw5aJFErk2LTKRkmXAORfjb4+qC5COXKTHV0k hogs5ssw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4j-004rDD-06; Sun, 04 Feb 2024 02:17:41 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 07/13] nfs: make nfs_set_verifier() safe for use in RCU pathwalk Date: Sun, 4 Feb 2024 02:17:33 +0000 Message-Id: <20240204021739.1157830-7-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro nfs_set_verifier() relies upon dentry being pinned; if that's the case, grabbing ->d_lock stabilizes ->d_parent and guarantees that ->d_parent points to a positive dentry. For something we'd run into in RCU mode that is *not* true - dentry might've been through dentry_kill() just as we grabbed ->d_lock, with its parent going through the same just as we get to into nfs_set_verifier_locked(). It might get to detaching inode (and zeroing ->d_inode) before nfs_set_verifier_locked() gets to fetching that; we get an oops as the result. That can happen in nfs{,4} ->d_revalidate(); the call chain in question is nfs_set_verifier_locked() <- nfs_set_verifier() <- nfs_lookup_revalidate_delegated() <- nfs{,4}_do_lookup_revalidate(). We have checked that the parent had been positive, but that's done before we get to nfs_set_verifier() and it's possible for memory pressure to pick our dentry as eviction candidate by that time. If that happens, back-to-back attempts to kill dentry and its parent are quite normal. Sure, in case of eviction we'll fail the ->d_seq check in the caller, but we need to survive until we return there... Signed-off-by: Al Viro Acked-by: Christian Brauner --- fs/nfs/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c8ecbe999059..ac505671efbd 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1431,9 +1431,9 @@ static bool nfs_verifier_is_delegated(struct dentry *dentry) static void nfs_set_verifier_locked(struct dentry *dentry, unsigned long verf) { struct inode *inode = d_inode(dentry); - struct inode *dir = d_inode(dentry->d_parent); + struct inode *dir = d_inode_rcu(dentry->d_parent); - if (!nfs_verify_change_attribute(dir, verf)) + if (!dir || !nfs_verify_change_attribute(dir, verf)) return; if (inode && NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) nfs_set_verifier_delegated(&verf); From patchwork Sun Feb 4 02:17:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544417 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C71977493; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=cTN3/BZ3Pl1Ao/qEDjDH4UBb7kWA/aFqFUZrYyZ3/UIe7qSKJpKVpLDIc+gz7FLIjcLq4F9nBb5oSqty+xRoVlku1SC2Ha/p3nevaW6/UK1O34j86j5XneCCnl+y1BuURwGroNZa+elNV8SD+1zAmulvJK+JXzzKvvo7iTNsCOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=zYRFksJtbabvYcgsGO42pYWYQgwk2Gd62aTtBhPPs+0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NS9U/2iTXFMxkmx3AbZBLCOh3lVGXC37JFEl4TSeWQ/oY4y1MVDv4l/PZhqTO7E40R7oUBT3ZrB61ck7WN00gBVEJruCSUip9fgo3oyYLIkPMeChUSQ4LlOpShoOparZuF0DOmCrSSB0+MOE4LidlgQhMrF3zJ4CB+Y+lefCWhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=TlrDjk3i; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="TlrDjk3i" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=hytpd6GUU8CfpGv7IEW9Pto33UoqqEf/lpKO/D7NPpA=; b=TlrDjk3io75QzP8iHfhoV/0Bna Uzb/gG6phRhbFCtrWMkk3GU49NqZTLEhhYUulAmuZwnsRab+gRCNXTmJGfmgLf8LWAiIbjnw1NU+R UvR738PhELzuQ4P78XLvQsuZcP2pkmotJEmPW1pvwY80SZIJpgKlR3fRPNFO+OGQgYJ3e8sMW6Qvr z/Dz/kqQ8xk6diRVanMZ1UUItKLlSccCHwPhGwcuO2ZEMPFRdKssA9C1gCOZIwR1u90BzAMr3X8sA A8kP9hr/+2wgV4iLVO6aFY5cH2by20WZrMMMrr1IdWxESkqndCKUIyIGDX0RWhncGodc9aDw9vcMj 5A8AFptw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4j-004rDK-0V; Sun, 04 Feb 2024 02:17:41 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 08/13] nfs: fix UAF on pathwalk running into umount Date: Sun, 4 Feb 2024 02:17:34 +0000 Message-Id: <20240204021739.1157830-8-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro NFS ->d_revalidate(), ->permission() and ->get_link() need to access some parts of nfs_server when called in RCU mode: server->flags server->caps *(server->io_stats) and, worst of all, call server->nfs_client->rpc_ops->have_delegation (the last one - as NFS_PROTO(inode)->have_delegation()). We really don't want to RCU-delay the entire nfs_free_server() (it would have to be done with schedule_work() from RCU callback, since it can't be made to run from interrupt context), but actual freeing of nfs_server and ->io_stats can be done via call_rcu() just fine. nfs_client part is handled simply by making nfs_free_client() use kfree_rcu(). Signed-off-by: Al Viro Acked-by: Christian Brauner --- fs/nfs/client.c | 13 ++++++++++--- include/linux/nfs_fs_sb.h | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 44eca51b2808..fbdc9ca80f71 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -246,7 +246,7 @@ void nfs_free_client(struct nfs_client *clp) put_nfs_version(clp->cl_nfs_mod); kfree(clp->cl_hostname); kfree(clp->cl_acceptor); - kfree(clp); + kfree_rcu(clp, rcu); } EXPORT_SYMBOL_GPL(nfs_free_client); @@ -1006,6 +1006,14 @@ struct nfs_server *nfs_alloc_server(void) } EXPORT_SYMBOL_GPL(nfs_alloc_server); +static void delayed_free(struct rcu_head *p) +{ + struct nfs_server *server = container_of(p, struct nfs_server, rcu); + + nfs_free_iostats(server->io_stats); + kfree(server); +} + /* * Free up a server record */ @@ -1031,10 +1039,9 @@ void nfs_free_server(struct nfs_server *server) ida_destroy(&server->lockowner_id); ida_destroy(&server->openowner_id); - nfs_free_iostats(server->io_stats); put_cred(server->cred); - kfree(server); nfs_release_automount_timer(); + call_rcu(&server->rcu, delayed_free); } EXPORT_SYMBOL_GPL(nfs_free_server); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index cd797e00fe35..92de074e63b9 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -124,6 +124,7 @@ struct nfs_client { char cl_ipaddr[48]; struct net *cl_net; struct list_head pending_cb_stateids; + struct rcu_head rcu; }; /* @@ -265,6 +266,7 @@ struct nfs_server { const struct cred *cred; bool has_sec_mnt_opts; struct kobject kobj; + struct rcu_head rcu; }; /* Server capabilities */ From patchwork Sun Feb 4 02:17:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544426 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C17E37491; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; cv=none; b=jMYy2hl+3uZdOuwvF69f1Jm+2xZj2pEruRZFW/SdBUZxcc8iNlH8tIspLHT5oegwxwLK7LONgL5qi0sV4mDd6ROFhWKk0UB4SkAR6b/EEdR6x5RTMmGX53GDYsKS4jjGf6cnmA9QQhPD9dKpcsAKWNJvT8JOaAhEJGlWJ072o1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; c=relaxed/simple; bh=f7WEO3vbtoP9xl5yKOL2rLQXCDxPEAWsYtSBPxBzmF0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bhw0H2n78TqGLB/fBUN03sKVM7fWJ4umDjdyu2T1z4mUc2dbS5JPRTEw3mbn5f4L4+w2s6th3E0siYPJlM6tKh0z55kNR3IKx6qOrNrbNOCu4Q+sY4Jtfc9Ixn6JHniuOySxLrbu0x0DcrFDtRaB9PpbQ+cPsfJxlaWNGHusm5o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=nEh+Ap5r; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="nEh+Ap5r" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=JeJspV0xyM95jRaGyJ36cYe2kvImon+4d20qpFr9x+A=; b=nEh+Ap5rp0DyclGgaHmmPb4tpl fYMd75Kdb5+ly9NAyH0EIZei/nUWPlhEb40rTLYJXdvEpbU8anWIM76zFjhV9pA0RoWDvAsvcFc1+ RDPHGcXPeiIECmX8iw5k6jcvsWTx4zCfKY2yKHfDSHKQdGtVw1YF3CHTjR5MKwyImrULNq1ncM1rF on5cBOXR4VmxJ0MapNHfUuC+518+Bvkla/luqlMd/QB3xxNPZMkcqgs7LANUZ6AT9J/1Y7gw5C81d Db/DQjvNN0U4GKvYJ6Hu7K86zY9KeISiyc82CJdRFCMLn74Ui95sVtAp8q/IXKNPBoj6qeNaPMYCw pONA1S5w==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4j-004rDS-1B; Sun, 04 Feb 2024 02:17:41 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 09/13] procfs: move dropping pde and pid from ->evict_inode() to ->free_inode() Date: Sun, 4 Feb 2024 02:17:35 +0000 Message-Id: <20240204021739.1157830-9-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro that keeps both around until struct inode is freed, making access to them safe from rcu-pathwalk Signed-off-by: Al Viro Acked-by: Christian Brauner --- fs/proc/base.c | 2 -- fs/proc/inode.c | 19 ++++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 98a031ac2648..18550c071d71 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1878,8 +1878,6 @@ void proc_pid_evict_inode(struct proc_inode *ei) hlist_del_init_rcu(&ei->sibling_inodes); spin_unlock(&pid->lock); } - - put_pid(pid); } struct inode *proc_pid_make_inode(struct super_block *sb, diff --git a/fs/proc/inode.c b/fs/proc/inode.c index b33e490e3fd9..05350f3c2812 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -30,7 +30,6 @@ static void proc_evict_inode(struct inode *inode) { - struct proc_dir_entry *de; struct ctl_table_header *head; struct proc_inode *ei = PROC_I(inode); @@ -38,17 +37,8 @@ static void proc_evict_inode(struct inode *inode) clear_inode(inode); /* Stop tracking associated processes */ - if (ei->pid) { + if (ei->pid) proc_pid_evict_inode(ei); - ei->pid = NULL; - } - - /* Let go of any associated proc directory entry */ - de = ei->pde; - if (de) { - pde_put(de); - ei->pde = NULL; - } head = ei->sysctl; if (head) { @@ -80,6 +70,13 @@ static struct inode *proc_alloc_inode(struct super_block *sb) static void proc_free_inode(struct inode *inode) { + struct proc_inode *ei = PROC_I(inode); + + if (ei->pid) + put_pid(ei->pid); + /* Let go of any associated proc directory entry */ + if (ei->pde) + pde_put(ei->pde); kmem_cache_free(proc_inode_cachep, PROC_I(inode)); } From patchwork Sun Feb 4 02:17:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544421 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 211407494; Sun, 4 Feb 2024 02:17:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; cv=none; b=Mwefz59v8HdRyr/TXEpF8JB9wTMY2wxxjdnaSiBN3uZPrfpJ/lAyyB/q4tdjq4jTr2Sjc+3dlI5rq+8EGcJf3CNAEDthE1X2+sDY3+SrrawNPexoBYqNdogM7q3xRI/sBKTCzF2StrqPcyWSQC8yek1K3ud/wavFNlaDza658aY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013064; c=relaxed/simple; bh=SRyqAW1bia3hA8WIBq/eWJxl2UkyBOHfh9gjJgn/9+U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Nl59LYbP2WLWFW/+YKCeBSaqJnpmaLZUzq4YJHisH4z7tKY2uoR6EKGHZbdNtM1SSZBMNYA0qa4m+Z8GI3URgPfGC3bJ4nTwWU/QS8il2hS6FSnnbS+T+Yq8CzlL/nt+CtC/rjDOBiGtdc66XfGB6lNODaJp5HMBcuutwa4eVhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=MOvylI1s; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="MOvylI1s" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=2MCHJybCgYaM+84/EVYU2f3B/ucLwt2OnRgR5X2eSlU=; b=MOvylI1sLs+VkTsnYxUlcCbdjL U50l+BmHsg3tffvDT9d+Smjpm0cjKfGXZSPSt3mG7t3Bb5+fFDcu84WFg+x72pucepx2+rF6GQ4Ey SiMfCD3rzV18SlgxemYbn0eb1WIznW5xyp4ReYtdeWxhUnBjwmUbQlf4GjbK2ev1UU7icsGP5sd+S GguhTeGgxzcmo4cGWHbHjDT49W1GnsR5je9PItjHESxyRME6ibDPEbNpU9UoB8MtHSFlwYrFaEf+D zV7qHDDsi61fysxfLLcPRSV0Uxs5QD6jzcfdWwQPhV7qMxZee2Ce+Hmm9ZPizVmc6OykF2silVbhj +M7GrRjw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4j-004rDW-1V; Sun, 04 Feb 2024 02:17:41 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 10/13] procfs: make freeing proc_fs_info rcu-delayed Date: Sun, 4 Feb 2024 02:17:36 +0000 Message-Id: <20240204021739.1157830-10-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro makes proc_pid_ns() safe from rcu pathwalk (put_pid_ns() is still synchronous, but that's not a problem - it does rcu-delay everything that needs to be) Signed-off-by: Al Viro Reviewed-by: Christian Brauner --- fs/proc/root.c | 2 +- include/linux/proc_fs.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/proc/root.c b/fs/proc/root.c index b55dbc70287b..06a297a27ba3 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -271,7 +271,7 @@ static void proc_kill_sb(struct super_block *sb) kill_anon_super(sb); put_pid_ns(fs_info->pid_ns); - kfree(fs_info); + kfree_rcu(fs_info, rcu); } static struct file_system_type proc_fs_type = { diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index de407e7c3b55..0b2a89854440 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -65,6 +65,7 @@ struct proc_fs_info { kgid_t pid_gid; enum proc_hidepid hide_pid; enum proc_pidonly pidonly; + struct rcu_head rcu; }; static inline struct proc_fs_info *proc_sb_info(struct super_block *sb) From patchwork Sun Feb 4 02:17:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544423 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F0127499; Sun, 4 Feb 2024 02:17:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; cv=none; b=f+B3g3Xtuc5B32sqCFzQFvtmcJKrukZojpy4cM6o+lTdYsFS0uUJWzTtgy7dRk7Q+qyiiZLMREbHvevi7cvujyVlUmrxWY5W20YV0AHn7eyeJbrzfl2NiG/squSdnuXvnEX8jl9RjMhIAmQoZJHONlKhgpThie1V3HbBjcLDTrE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; c=relaxed/simple; bh=wKYT0Nl+K9iZIU8uK5fkG6hh9J3hSCBbl3yHV/LUoDo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=A1fChYy2RjxnF0kyida8/awSXvjqJh9tw+yLaxU49pT72R2ZH7YynC7Yuew1/UdJxPPaVG4twUtKDpg1hLMevXMmp/G64miXrTT7/2r1TGI4AgxV3CnaTeU5VuzGVV8NSGxxqL2XPEl/NvfNcE+HLtYQHVd/omr3+dOWas0CK74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=rK7OcwXI; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="rK7OcwXI" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=vV6DklX0PI+1e7tA40Z3BWWdMFq/uG8yRMvN+zPvgKs=; b=rK7OcwXIXOaVllu2KNzDxZowuI wbBANOVrVmrbcRTFnARcE6G7eS6j9xkFrtr5FxwfK6QJwAvRAS+JnJz88QOw5l3aNe1HE+SaECS/n fMfZzbNZ+Af3QnG4ZYSy5gKaB7RjbDSprs/eEWnS1cmBS6SBK+HaXUB9/4x4beWEjZuUeCKI+6D+m wU62PKZkRAmchB+GMltzJuqimvsG5j/+e6KBNGxzD5srUUthwS8+CHJk4YIViWE0s5JPLI89V2lGY lcga2aOJAuyjvuAhFZgHYPZXFTz68iS8S5GpfnD6Wfp6KuAhZZxZYN71ly5x5HbFd2PJiFuT0n1+T WHAObTIA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4j-004rDc-1u; Sun, 04 Feb 2024 02:17:41 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 11/13] fuse: fix UAF in rcu pathwalks Date: Sun, 4 Feb 2024 02:17:37 +0000 Message-Id: <20240204021739.1157830-11-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro ->permission(), ->get_link() and ->inode_get_acl() might dereference ->s_fs_info (and, in case of ->permission(), ->s_fs_info->fc->user_ns as well) when called from rcu pathwalk. Freeing ->s_fs_info->fc is rcu-delayed; we need to make freeing ->s_fs_info and dropping ->user_ns rcu-delayed too. Signed-off-by: Al Viro Reviewed-by: Christian Brauner Acked-by: Miklos Szeredi --- fs/fuse/cuse.c | 3 +-- fs/fuse/fuse_i.h | 1 + fs/fuse/inode.c | 15 +++++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 91e89e68177e..b6cad106c37e 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -474,8 +474,7 @@ static int cuse_send_init(struct cuse_conn *cc) static void cuse_fc_release(struct fuse_conn *fc) { - struct cuse_conn *cc = fc_to_cc(fc); - kfree_rcu(cc, fc.rcu); + kfree(fc_to_cc(fc)); } /** diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 1df83eebda92..bcbe34488862 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -888,6 +888,7 @@ struct fuse_mount { /* Entry on fc->mounts */ struct list_head fc_entry; + struct rcu_head rcu; }; static inline struct fuse_mount *get_fuse_mount_super(struct super_block *sb) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 2a6d44f91729..516ea2979a90 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -930,6 +930,14 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm, } EXPORT_SYMBOL_GPL(fuse_conn_init); +static void delayed_release(struct rcu_head *p) +{ + struct fuse_conn *fc = container_of(p, struct fuse_conn, rcu); + + put_user_ns(fc->user_ns); + fc->release(fc); +} + void fuse_conn_put(struct fuse_conn *fc) { if (refcount_dec_and_test(&fc->count)) { @@ -941,13 +949,12 @@ void fuse_conn_put(struct fuse_conn *fc) if (fiq->ops->release) fiq->ops->release(fiq); put_pid_ns(fc->pid_ns); - put_user_ns(fc->user_ns); bucket = rcu_dereference_protected(fc->curr_bucket, 1); if (bucket) { WARN_ON(atomic_read(&bucket->count) != 1); kfree(bucket); } - fc->release(fc); + call_rcu(&fc->rcu, delayed_release); } } EXPORT_SYMBOL_GPL(fuse_conn_put); @@ -1366,7 +1373,7 @@ EXPORT_SYMBOL_GPL(fuse_send_init); void fuse_free_conn(struct fuse_conn *fc) { WARN_ON(!list_empty(&fc->devices)); - kfree_rcu(fc, rcu); + kfree(fc); } EXPORT_SYMBOL_GPL(fuse_free_conn); @@ -1902,7 +1909,7 @@ static void fuse_sb_destroy(struct super_block *sb) void fuse_mount_destroy(struct fuse_mount *fm) { fuse_conn_put(fm->fc); - kfree(fm); + kfree_rcu(fm, rcu); } EXPORT_SYMBOL(fuse_mount_destroy); From patchwork Sun Feb 4 02:17:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544424 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85D2B749C; Sun, 4 Feb 2024 02:17:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; cv=none; b=jfLvxtTpc6wWAPQCaFJHwQBPXlmgwHTynKLLVJHED+eo70cVw1n/fYZfJJhlRP/WOmqhvEvx5XXALi2DzZ4k3/REpawENCsp2/VyFCB8y/KyxfCapT+7Qov/oX1ATm5LYRDGpTBS+Fac1uCkSdM+ZIW+9db+5vSri6dGW+acatQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; c=relaxed/simple; bh=gXEyVGfpVHTOGscWWhhgTHNWTU3KHsLHDUa7ooHXJ5o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KVOcfaACsb3SCUT9GSk7g9N7fyNSzlV7nHvR6f2ljwjj4yEuMvf2O3BQERIVmWf7AB+wFtF0NFJpQlaxesCZQgAFC+Iwb69e5NUCx3AR/3B6kwVIQhKzcQO+ZOKkflrx4J76RFh0Pr6weRRLj+PrxtSldHcsofpRvgA3qF6xbLk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=AZCOjPLC; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="AZCOjPLC" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=iVQFpkDCs9bj7WoZx+TN7eoBXzYpcdd2k1cx6KhK2YE=; b=AZCOjPLCvnzbtVNGM2vVDCasqK x2oOq7AbqjQtdx49CbQbf3ISp5j4Qjov/GCNC9krD+rtADL0gq4WJa6RtZDJnrwZi6CoszxXme8V1 9lsLsLsYd/Uyi09TVPGmavjzvmZ5f7wUu/Qdt4FRfjXBLGZ8cwe8MlBWDYdmBJ8v5xJM/hk8MNFrZ fTImNAv++iorzdLcnASa8Iu39QmdHty+M+wvWFHQXsib4yViHV/GrchrzNbLYduCYN/MGYg0C1KkA X7GIedptDhXNj+CL9F6y4Mf0WLhWdo3H1Zhoe2eTgE+VlqdZZfAX+PLi/NGJ95aBojiuNI2No5CYz beFWXBjw==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4j-004rDi-2X; Sun, 04 Feb 2024 02:17:41 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 12/13] cifs_get_link(): bail out in unsafe case Date: Sun, 4 Feb 2024 02:17:38 +0000 Message-Id: <20240204021739.1157830-12-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro ->d_revalidate() bails out there, anyway. It's not enough to prevent getting into ->get_link() in RCU mode, but that could happen only in a very contrieved setup. Not worth trying to do anything fancy here unless ->d_revalidate() stops kicking out of RCU mode at least in some cases. Signed-off-by: Al Viro --- fs/smb/client/cifsfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index e902de4e475a..630e74628dfe 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1172,6 +1172,9 @@ const char *cifs_get_link(struct dentry *dentry, struct inode *inode, { char *target_path; + if (!dentry) + return ERR_PTR(-ECHILD); + target_path = kmalloc(PATH_MAX, GFP_KERNEL); if (!target_path) return ERR_PTR(-ENOMEM); From patchwork Sun Feb 4 02:17:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13544425 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [62.89.141.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85D5D79C1; Sun, 4 Feb 2024 02:17:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=62.89.141.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; cv=none; b=Vwy8ZQeN1QY14/mF2ln1O8QkCnThr/dIpuSg/bbTTXf9aFnUhxIJ2Wccvl/HoqS73dkJOgtfHG3s2fOQLGfQjRy+eXsgworGdl1ZpfkT0ab0cbQR2XXmfpAb0L83Ta8AqtoPAWDTzOO52o+4zKBBXB3UL0w62SZP8geZzPsK4TY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707013065; c=relaxed/simple; bh=y54nHQkPOl359AVYAtuuO+KK5TXGw8vABwwc1x2IPbk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bQ7u+0tChuGfKcMt0a1YLRZXkQd2YGRj+MVNiV6iJXLiKWdi8nzMbnKSU9lXqS68M6qYbuvl0BQGQ5vCggkvUs2YjvjDZd8+YWIFWlHk+SkA6QiZyWnU29qNmr287ySGizaG2nt6LrbxAwWvVZmRzFitxB1kMquZTs4gqjz3Qwk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk; spf=none smtp.mailfrom=ftp.linux.org.uk; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b=F/db2XFg; arc=none smtp.client-ip=62.89.141.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zeniv.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ftp.linux.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linux.org.uk header.i=@linux.org.uk header.b="F/db2XFg" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description; bh=cuFhGgNbk5LHRay7zOGcHPlnB60egP7ycJDnEl7eO64=; b=F/db2XFgUPBdiv/ecH+HGw4r7+ jHgTBCznaicUuHEoLs0TjVoyi0YO4LRxQjgMlEcDleaiOCi/JbMKLglgJ8fC96Hh3AVrcOUKLPVoW x3pBPoK+WdflalrUN5AgC7OkMjQqEZmNkZfe21v0PH06RNlJ0LJFtNEtPYp1VnbMplhdRvZlVQEiW D0gkE9Tsc7Whe7xRXjuEDKgjhsZubJCyjOhHUpllu0uF8IV7J/5cSEFa1ia2K5HyjOlDBg4E5KWv7 dVP0/l1+1X1J/XHhT5P2a2p1t4CjzcyMsIrf3fUGxjRhTw8LlhGtnA/t45qG2L6BhyN4KKLvd35Kw gbmINdHA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1rWS4j-004rDo-3C; Sun, 04 Feb 2024 02:17:42 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , Christian Brauner , linux-ext4@vger.kernel.org, linux-nfs@vger.kernel.org, Miklos Szeredi , linux-cifs@vger.kernel.org Subject: [PATCH 13/13] ext4_get_link(): fix breakage in RCU mode Date: Sun, 4 Feb 2024 02:17:39 +0000 Message-Id: <20240204021739.1157830-13-viro@zeniv.linux.org.uk> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240204021739.1157830-1-viro@zeniv.linux.org.uk> References: <20240204021436.GH2087318@ZenIV> <20240204021739.1157830-1-viro@zeniv.linux.org.uk> Precedence: bulk X-Mailing-List: linux-cifs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Sender: Al Viro 1) errors from ext4_getblk() should not be propagated to caller unless we are really sure that we would've gotten the same error in non-RCU pathwalk. 2) we leak buffer_heads if ext4_getblk() is successful, but bh is not uptodate. Signed-off-by: Al Viro --- fs/ext4/symlink.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c index 75bf1f88843c..645240cc0229 100644 --- a/fs/ext4/symlink.c +++ b/fs/ext4/symlink.c @@ -92,10 +92,12 @@ static const char *ext4_get_link(struct dentry *dentry, struct inode *inode, if (!dentry) { bh = ext4_getblk(NULL, inode, 0, EXT4_GET_BLOCKS_CACHED_NOWAIT); - if (IS_ERR(bh)) - return ERR_CAST(bh); - if (!bh || !ext4_buffer_uptodate(bh)) + if (IS_ERR(bh) || !bh) return ERR_PTR(-ECHILD); + if (!ext4_buffer_uptodate(bh)) { + brelse(bh); + return ERR_PTR(-ECHILD); + } } else { bh = ext4_bread(NULL, inode, 0, 0); if (IS_ERR(bh))