From patchwork Mon Oct 2 02:29:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405505 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F9EBE784A7 for ; Mon, 2 Oct 2023 02:29:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235342AbjJBC3e (ORCPT ); Sun, 1 Oct 2023 22:29:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58608 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBC3d (ORCPT ); Sun, 1 Oct 2023 22:29:33 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91D8099 for ; Sun, 1 Oct 2023 19:29:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=7qtssQeJsjUASDuYOM8OQSYDchLVAVU547/17cTtVxo=; b=EvUU3h41JyQfOgifStLhmdnZEK AFDoR/DAE2GnHpOZXj4M97g2m8wRrv2eMLNsK8l+iMEhKoNuqAhzihHaMljN23SBNbYG46nXR9fGL 2QNg8sqPpe0fM/0nNvMR8WYygEPFwHIdoh73bML35DDTl6WuyABzImFze9TknSSYK7yhZSYKBYOS3 nVDMgKzvo0u8FT47zEvdSpNEcxf1nv087qEo4zF15j/fzEtK19wfwzLkR4wTew4/NgLZvaUKBrqxb LM+AgITV5t5HAi9pYAyCFBoSWkerZUWFVVpxliv/5TJmyNedkWMKGRpnQArNeyAgh9t7i2xwjHBlF vkz7AX6Q==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8gb-00EDoa-2M; Mon, 02 Oct 2023 02:29:29 +0000 Date: Mon, 2 Oct 2023 03:29:29 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 01/15] rcu pathwalk: prevent bogus hard errors from may_lookup() Message-ID: <20231002022929.GB3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org 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 --- fs/namei.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index 567ee547492b..2494561a21fe 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 Mon Oct 2 02:30:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405506 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F374FE784A7 for ; Mon, 2 Oct 2023 02:30:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235120AbjJBCaV (ORCPT ); Sun, 1 Oct 2023 22:30:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38782 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCaU (ORCPT ); Sun, 1 Oct 2023 22:30:20 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9932199 for ; Sun, 1 Oct 2023 19:30:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=1pGQQGV1uCgaPeHnwp4pkr+zNvPLm/SXzWPox8KGdic=; b=vz5Y5BoxcYxKOhm1Wki+kXmSPZ WOp52AyA++wrFPBLbS/EVOlY8UXt96Ett+g9fLvz2Fw9tASUvcFTVy86FYyi2ioagojTMvS5ihsWg c0WorlXOGS8lpoYwee91Rkb8hTKTA7p6Esz+07748hLqZ/PGLQrdOQg5SXXF0pAu8BmiIHG6UrzhW vExSyTxa+0qOHBFGqhAO6FZMqBdCuTBmsKrx7tjJBh6yK1N/4+QOUkoHE9p6dryXlHWg2UeFhlq5d qC61dSqB/O+SCrPwkLL2tG0FyG5srqXbcNE0brAkbb1TnWk03JKNkLrJVEC6+45oBEJt1yghYb00J XlPNXA/A==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8hL-00EDpj-2I; Mon, 02 Oct 2023 02:30:15 +0000 Date: Mon, 2 Oct 2023 03:30:15 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 02/15] exfat: move freeing sbi, upcase table and dropping nls into rcu-delayed helper Message-ID: <20231002023015.GC3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org 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 --- 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 f55498e5c23d..22e17b0a66e8 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -273,6 +273,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 2778bd9b631e..593cfff8c6f4 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) @@ -593,7 +590,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); @@ -606,8 +603,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; @@ -694,12 +689,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; } @@ -764,13 +757,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 Mon Oct 2 02:30:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405507 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F6D0E784A8 for ; Mon, 2 Oct 2023 02:30:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235396AbjJBCay (ORCPT ); Sun, 1 Oct 2023 22:30:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235137AbjJBCax (ORCPT ); Sun, 1 Oct 2023 22:30:53 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16F81CE for ; Sun, 1 Oct 2023 19:30:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=Ug2Y34xz5+mbpB8ClVi23teq0mMkMZtGfWZr82RpmBQ=; b=XKsIvh7OqmANv2S3hQQOts+npj lngoZ8szVr4NNYSzdeu12RXhtWNdd0/RSlG0I/eiTe1cVuuzkMlBznQpvjGyvUOyWI5hci/p40rzp vLv+RSk7yqps70ywFEPyyDK9KL/q7AXNOKuqQktNP5rhpXMk1puDbrSOGHmAG3XGNlD/RMnBcStjT /hguLELyVjpfmxieNDNi9R9fTrIqy56xXvxSHbfbec3Ydlvl5OTQdarZZaqWlVJuHw7UI3fa0KBH+ w1BxTEkcJFMI6ZGOaOm+VaIo37oh7qNuWupvUiDEoYdwAcpwm99vTIFYUDV6c17zuQe6S6V9kyzSD TOiXkVdA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8ht-00EDql-1S; Mon, 02 Oct 2023 02:30:49 +0000 Date: Mon, 2 Oct 2023 03:30:49 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 03/15] affs: free affs_sb_info with kfree_rcu() Message-ID: <20231002023049.GD3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org one of the flags in it is used by ->d_hash()/->d_compare() Signed-off-by: Al Viro --- 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 Mon Oct 2 02:31:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405508 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A696E784A7 for ; Mon, 2 Oct 2023 02:31:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235212AbjJBCbb (ORCPT ); Sun, 1 Oct 2023 22:31:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54206 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235137AbjJBCbb (ORCPT ); Sun, 1 Oct 2023 22:31:31 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 826A999 for ; Sun, 1 Oct 2023 19:31:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=EjWkAFYMC0New8r7aI9BMXvNYwHQVwhCzm32GsCIcMM=; b=LNMOzE9HNjI7l5/HOfjK+R9TjL OD8Xi7CUMgF7CBxoST/Qqex7A8cDPOijTTQmtc5dzf+nH5BDzkblTiP+Dj8+o26F7NUS5kWBeTBgI In6daHJa3mTHaaNOqUoV+w4amdJL3M6Gpi3whG+dlKRUDhUfGRdZjknPq5YqFqp471zbSQAjW1MM8 v1DmLAbPmq9urd69IA1G3EKrrM3dOusLfXAvPROys5sgUws9m/fCBlDtr3GLuxonk63cixh0vhfR4 hyNfc5ODFb5mql2YfVQRXcpMC9ihbJr/H/ru6ukvcaPLQ6y7LtVIL5CQQxkNetXyJR76ozg7hk4VU wqJxHU+A==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8iT-00EDrb-2C; Mon, 02 Oct 2023 02:31:25 +0000 Date: Mon, 2 Oct 2023 03:31:25 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 04/15] hfsplus: switch to rcu-delayed unloading of nls and freeing ->s_fs_info Message-ID: <20231002023125.GE3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org ->d_hash() and ->d_compare() use those, so we need to delay freeing them. Signed-off-by: Al Viro --- 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 Mon Oct 2 02:31:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405509 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 440D0E784A7 for ; Mon, 2 Oct 2023 02:31:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235342AbjJBCb4 (ORCPT ); Sun, 1 Oct 2023 22:31:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235137AbjJBCbz (ORCPT ); Sun, 1 Oct 2023 22:31:55 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE40399 for ; Sun, 1 Oct 2023 19:31:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=4AnR85rsjiuD1oFzzScjoOARp5ltt5SGcQanpgN2lOg=; b=LKSK1Ymt22gwkXB6byW2clLd2F daEwEw1Cc7cTEiCbbAxlVOR0g4/+Edvl12K8peZmTppyQHalYwAuAzfVR6j+k45RiRvIfwja8xL6L NJRTfD2Cmq9ygJucZ0kgtvbrUHv2Ro61SA6Nw6fDP1NHQFDYXYKBRLbUxyCyOYDIqiszorbohAcSz mSUmyfIksV64LEOlOJHI76i3fmhWyOVcD73sBG4uph56yp5y0kernPtTpQJOCjbPzlXFRe7ixgN7X 8LYHrLLXuh+eMM00m/ukVYs/1OIHYHuGEr0X2uJ5VV97NTqg3IrLqmGg19FZ/HCxQ12Tz5iXvgMN0 GcqMT9WQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8is-00EDsP-1a; Mon, 02 Oct 2023 02:31:50 +0000 Date: Mon, 2 Oct 2023 03:31:50 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 05/15] cifs_get_link(): bail out in unsafe case Message-ID: <20231002023150.GF3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org ->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 22869cda1356..2b044e47a3a6 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1170,6 +1170,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 Mon Oct 2 02:32:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405510 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A95DAE784A6 for ; Mon, 2 Oct 2023 02:32:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235137AbjJBCch (ORCPT ); Sun, 1 Oct 2023 22:32:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCcg (ORCPT ); Sun, 1 Oct 2023 22:32:36 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C21899 for ; Sun, 1 Oct 2023 19:32:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=PfMFJEm5A7yLka9iOS31iWCBDEFtH0eaxQuSkPNFxSQ=; b=MRCHqgAXpo2u+0MxKwODfG67iD Y1OgSCLcKjG9W0S/mcP9BKVa1EK3yM5GuvElFuWcQTBL4J9uNBhDJ5jjBo1dpo5O+tOyNcjnI4MD1 PK2IDEPfMw7lggUT80oJmXRMyIRDkvHkr39MtbQjj8Mmw27NjiRQjMFqu3q2z6IT3SAjCM1qZ7bZK XZHUbVGDGEX4QVSG1W2Y4Kxeb51+fwxf+Mw7NVp5yBqST329q4X++FQqTlUYldIOds64hVK+mDEHC ep5n70+o3J1YCq+IalCKKHLVycbGPQRrq/NyFFQPenwDdXxjNq8+24BiHiscQCEl38OIdSSfBCaDZ glq5H6AQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8jY-00EDtp-02; Mon, 02 Oct 2023 02:32:32 +0000 Date: Mon, 2 Oct 2023 03:32:31 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 06/15] procfs: move dropping pde and pid from ->evict_inode() to ->free_inode() Message-ID: <20231002023231.GG3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org that keeps both around until struct inode is freed, making access to them safe from rcu-pathwalk Signed-off-by: Al Viro --- 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 ffd54617c354..8e93b11a0fed 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1881,8 +1881,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 532dc9d240f7..c83e1a55da42 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 Mon Oct 2 02:33:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405511 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29679E784A6 for ; Mon, 2 Oct 2023 02:33:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235377AbjJBCdN (ORCPT ); Sun, 1 Oct 2023 22:33:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCdM (ORCPT ); Sun, 1 Oct 2023 22:33:12 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8422199 for ; Sun, 1 Oct 2023 19:33:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=Jr3LRvkagY6xKaUxMwPrFP/7310J+gLk9DTRF6npBoc=; b=SGE2uq4Go7mJVGzis76cGzY5Nt OZwAwKqlJ6jIHRyfs7yHvZ5YDdeH+6x7QWTg96Luy2sXC3W2almmCEIYvdm5OR2s0+58YKQwt4GWA ZSKZG4T+vl9HMr8ad1zp8PkdoODfBC55rpWRra02SjjGlxqcpH/9Arfw5qgOuBFLp4r1pDapAGD+Q tKwih81Zmg4aeKyGv2fiyO7RdaXhV6xIOA5RGsRldtQjM+P5kA5UvqO5j1VC0StHfN1X2c3xucXrs 6x9ETCzBfvW33/FOkxjSgdpnRfwhvvcuVerCEUgAfnSET6Kqlw7NJ/libRyZkRtDzVWbRGcuP4FcS TL/zrN6Q==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8k8-00EDuS-2q; Mon, 02 Oct 2023 02:33:08 +0000 Date: Mon, 2 Oct 2023 03:33:08 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 07/15] procfs: make freeing proc_fs_info rcu-delayed Message-ID: <20231002023308.GH3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org 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 --- 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 9191248f2dac..d3148e1d883b 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 Mon Oct 2 02:33:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405512 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69016E784A6 for ; Mon, 2 Oct 2023 02:33:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235394AbjJBCdu (ORCPT ); Sun, 1 Oct 2023 22:33:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCdt (ORCPT ); Sun, 1 Oct 2023 22:33:49 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0412D99 for ; Sun, 1 Oct 2023 19:33:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=YGUB7+0S4VDddH1q/fCsHmff00CJWUlUMj8uNvOPmg8=; b=j+xIKKQS+DutobP0VSDrLYpLb/ lPErEBNxJRabPpGsxXnL01HWjqE/PQmYeJc6K/4uBcSaPMJMRlaXWh2OEuM9ATk8hSZklA7m/8A9T DEM9D9CfnbnFfhIsxa4F997pcCW6orrw7V3rjFSTPxD1+FLOaburFBfBg0FfBHqzZ5lbPVQL05DEv 6wheMCcBY7+tmXhDoEqtZ1SB5MWxYfOdTK1mNpYx2vk5yTicsui01p5Y5p2KzDT4R5z/zPR0Nm0Po 5iYa8ayMnPlyYDmvmswfm/aw9KEsgXR0ctj17g/sWZWvCX3/cY3onnAZ7V0SazqeWJedko8+NhjZn o+dMMW0A==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8ki-00EDvT-2E; Mon, 02 Oct 2023 02:33:44 +0000 Date: Mon, 2 Oct 2023 03:33:44 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 08/15] gfs2: fix an oops in gfs2_permission() Message-ID: <20231002023344.GI3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org in RCU mode we might race with gfs2_evict_inode(), which zeroes ->i_gl. Freeing of the object it points to is RCU-delayed, so if we manage to fetch the pointer before it's been replaced with NULL, we are fine. Check if we'd fetched NULL and treat that as "bail out and tell the caller to get out of RCU mode". Signed-off-by: Al Viro --- fs/gfs2/inode.c | 6 ++++-- fs/gfs2/super.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 0eac04507904..e2432c327599 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1868,14 +1868,16 @@ int gfs2_permission(struct mnt_idmap *idmap, struct inode *inode, { struct gfs2_inode *ip; struct gfs2_holder i_gh; + struct gfs2_glock *gl; int error; gfs2_holder_mark_uninitialized(&i_gh); ip = GFS2_I(inode); - if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { + gl = rcu_dereference(ip->i_gl); + if (!gl || gfs2_glock_is_locked_by_me(gl) == NULL) { if (mask & MAY_NOT_BLOCK) return -ECHILD; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); if (error) return error; } diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 02d93da21b2b..0dd5641990b9 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1550,7 +1550,7 @@ static void gfs2_evict_inode(struct inode *inode) wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE); gfs2_glock_add_to_lru(ip->i_gl); gfs2_glock_put_eventually(ip->i_gl); - ip->i_gl = NULL; + rcu_assign_pointer(ip->i_gl, NULL); } } From patchwork Mon Oct 2 02:34:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405513 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DAFD6E784A7 for ; Mon, 2 Oct 2023 02:34:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235396AbjJBCeV (ORCPT ); Sun, 1 Oct 2023 22:34:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCeV (ORCPT ); Sun, 1 Oct 2023 22:34:21 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E8F4C9 for ; Sun, 1 Oct 2023 19:34:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=Ei3uI6cTnZl/1dVU+F9NiIsmbxC2qsdW7ypmVtPBOB0=; b=bj5e4xKMx0OGtympFCMd0zBsKH 09xGajJhIoLMgja0HmmP/BGX+QDowTqBe6TSeLXYb3/S4HBIu5MyXHP/Iobi11nPnagizE9PyCinc 1ufsduIYV13JnhQRp5Qt6e/Sm9cT+M1W2I4uJ0nv0axFvhqBbCji/qSQF3FeL+RV2gnvVSjCBDwKl bMecnGL0Fycm+qzu+QMKWR/Q7kg1XFKIZGwtMQB6uavYJNcxUx2EXCoaZ+HJ12i5JV064xlAC/w9B dzJNisikbWM5vo7Tvxz1HgAY05pjpF8thc7zX2RSKfCKOtR/9lYiaeoq1k10Zveb/BhJAKjZKInPN NoyAk/IQ==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8lE-00EDw2-31; Mon, 02 Oct 2023 02:34:17 +0000 Date: Mon, 2 Oct 2023 03:34:16 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 09/15] nfs: make nfs_set_verifier() safe for use in RCU pathwalk Message-ID: <20231002023416.GJ3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org 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(); we check that parent is 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. Signed-off-by: Al Viro --- 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 e6a51fd94fea..8ffc1f78ba51 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 Mon Oct 2 02:34:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405514 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E581FE784A7 for ; Mon, 2 Oct 2023 02:34:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235342AbjJBCfB (ORCPT ); Sun, 1 Oct 2023 22:35:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCfA (ORCPT ); Sun, 1 Oct 2023 22:35:00 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1782BCE for ; Sun, 1 Oct 2023 19:34:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=EbwDiolze3U4QPmXm+BW52LaQUDPZmPACbWujMd5Kfg=; b=C0fxxBfI2TW91B+ihO3RoJCuJT KY2O1civkUDuN2gD+Tor7JeSIKH5J5LnKLhEp3B/RQZC/lLTAfFUazAtF/Lr4ktpkkwYlW9gbuhjI lV2FWbf097yfCeR6FD62HvIKLCiV0NYkZ8LPVozd/UnBN416YPJRjCFhWDGjJhAalCq6VEUCUgtWw UjF8wAcLx/CUrxdMRF4wxeK9v3agU5Uiy2pjIYe23fjm7oO9Dk7ElhcdfWRabUI2DbjHmKQpwRS6H 8A+s8HLSvsP8wWyUCyPKbNtv4zqI50MlMPstTWhfnFp5BpmXcGQV8JIocT0NMqwzaB1ZGyaxTyjno Ldi1WmYg==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8ls-00EDxB-1J; Mon, 02 Oct 2023 02:34:56 +0000 Date: Mon, 2 Oct 2023 03:34:56 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 10/15] nfs: fix UAF on pathwalk running into umount Message-ID: <20231002023456.GK3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org 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 --- 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 cd628c4b011e..4bd16da65c05 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; }; /* @@ -264,6 +265,7 @@ struct nfs_server { const struct cred *cred; bool has_sec_mnt_opts; struct kobject kobj; + struct rcu_head rcu; }; /* Server capabilities */ From patchwork Mon Oct 2 02:35:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405515 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFF38E784A7 for ; Mon, 2 Oct 2023 02:35:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235336AbjJBCf0 (ORCPT ); Sun, 1 Oct 2023 22:35:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56946 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCfZ (ORCPT ); Sun, 1 Oct 2023 22:35:25 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64381A7 for ; Sun, 1 Oct 2023 19:35:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=Stmulw48FdcNh/sko1+XXezL/Lvn9Cb50aXxMLdgwF8=; b=eJsWYDu1NTflig0onPEEh0pWvH Ow4GzqHF/CklTIgec8B7h08CElswTobBDdgFqMuN8dYD0JcYvQAruxk5Dzi3cUlhDNyLe3gmNlJDZ /cMxwOVSOKI9dKz/19bmHUlvinTnFVSj9AgGvoVMwICTUrVNqgPLJZdRxodcIAj5kakGUUoIWsw5v 3m/bMezhzC+SGdp4pcgxSQQqRKU+S4IwJ1+JBeNDavBO6nY6AYFCmzjnXLo46fBeRd8EhNq1qndIX g4iBSMaPaM6Wen3WhRq23x3M3lMF9akvv7sn8g6ZqgvoUer3n6/EZYcSjWPRPOzMnnS/c5qFsOFhZ xuOLOgEg==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8mH-00EDxn-2J; Mon, 02 Oct 2023 02:35:21 +0000 Date: Mon, 2 Oct 2023 03:35:21 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 11/15] fuse: fix UAF in rcu pathwalks Message-ID: <20231002023521.GL3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org ->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 --- 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 bf0b85d0b95c..0c45014fbb03 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -873,6 +873,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 2e4eb7cf26fb..e13c9312cb55 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -881,6 +881,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)) { @@ -892,13 +900,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); @@ -1316,7 +1323,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); @@ -1833,7 +1840,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 Mon Oct 2 02:35:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405516 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F09CBE784A7 for ; Mon, 2 Oct 2023 02:35:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235399AbjJBCfu (ORCPT ); Sun, 1 Oct 2023 22:35:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCft (ORCPT ); Sun, 1 Oct 2023 22:35:49 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52B4AA7 for ; Sun, 1 Oct 2023 19:35:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=EewcqI+Ox5ekxQxUglqzLiq/FvSzeoK/B4dyiwaADCs=; b=PsJIJ3ivSQByKwOMBtumcyoupc g6mhCPrAp7S+NeEjzIY8xVp+ob2NWWEduzl/83qwOCOtb4XTOfCIi4ZxNV4CZPVHj0YX0IkANY2yR 17P+NL3LCfTaMci4RdXH6s0IkQN69NgyLODWAgzJvtB8gxtBMIm91MgsTwcN/oE604HZPrcWP/c82 2sopADg6YhH+tRPSAg4tmzr8VQpTMcsG/4solf5Ljpc26+vqLLNze57rkwAEsutLPpWD4z0Z5BrAb UozVoxLlycd3hybAEnzOyCgd0m9bCccNQMNLTyNIxelcJPuD4+Vqx1DP73P/go/u93eqmfiLoDZRG g1ScOkbg==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8mf-00EDyN-1d; Mon, 02 Oct 2023 02:35:45 +0000 Date: Mon, 2 Oct 2023 03:35:45 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 12/15] afs: fix __afs_break_callback() / afs_drop_open_mmap() race Message-ID: <20231002023545.GM3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org 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 --- 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 d37dd201752b..0012ea300eb5 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -529,13 +529,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->cell->fs_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->cell->fs_open_mmaps_lock); flush_work(&vnode->cb_work); From patchwork Mon Oct 2 02:36:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405517 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2B1AE784A6 for ; Mon, 2 Oct 2023 02:36:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235394AbjJBCgS (ORCPT ); Sun, 1 Oct 2023 22:36:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234639AbjJBCgS (ORCPT ); Sun, 1 Oct 2023 22:36:18 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC853CE for ; Sun, 1 Oct 2023 19:36:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=CnyoubvrTYwdXJkYsciRIhEb5IygrGOOq4H2i/Xv+rA=; b=UFn+Awi3DErcvTV1wvHcTbtrs3 OTSnsxC8r017Vs9422JIn+t29GCysTBk7pVoshBKjPHrpWiGHWTUpFmG+iZJUjU9hdn8iFI1sUIp6 8qWowzh1SfnpGESp0635gIzkVZQnRJeh2hCTJGUI2vne9xs4KixHBe2N1So9sbkdRq/N/5pXMxiD+ fSTiEjc+grMT+oiXsc4AcEtSb4FPcMLkUmnQJTBOdFC3cKHkuXEmpYVgm4sYK3GzwXHNjCoyQABU5 FQE6IolsW1eTWhy7LAURKaKV/V4BQpZC38bjFl7DqwFMbOy1ve8/hXI0oU42Y2p0fS6zacO/HD90f LQU1GPdA==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8n7-00EDz8-14; Mon, 02 Oct 2023 02:36:13 +0000 Date: Mon, 2 Oct 2023 03:36:13 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 13/15] overlayfs: move freeing ovl_entry past rcu delay Message-ID: <20231002023613.GN3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002022846.GA3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org ... into ->free_inode(), that is. Fixes: 0af950f57fef "ovl: move ovl_entry into ovl_inode" Signed-off-by: Al Viro Reviewed-by: Amir Goldstein --- fs/overlayfs/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index def266b5e2a3..f09184b865ec 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -167,6 +167,7 @@ static void ovl_free_inode(struct inode *inode) struct ovl_inode *oi = OVL_I(inode); kfree(oi->redirect); + kfree(oi->oe); mutex_destroy(&oi->lock); kmem_cache_free(ovl_inode_cachep, oi); } @@ -176,7 +177,7 @@ static void ovl_destroy_inode(struct inode *inode) struct ovl_inode *oi = OVL_I(inode); dput(oi->__upperdentry); - ovl_free_entry(oi->oe); + ovl_stack_put(ovl_lowerstack(oi->oe), ovl_numlower(oi->oe)); if (S_ISDIR(inode->i_mode)) ovl_dir_cache_free(inode); else From patchwork Mon Oct 2 02:36:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405518 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AEB3CE784A7 for ; Mon, 2 Oct 2023 02:36:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235407AbjJBCgr (ORCPT ); Sun, 1 Oct 2023 22:36:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235396AbjJBCgq (ORCPT ); Sun, 1 Oct 2023 22:36:46 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2BC8CE for ; Sun, 1 Oct 2023 19:36:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=tQHM/Q4vObkj4H32QkFiMX0KySqsWMREApB37lCIJpA=; b=FQnc6Zz3dlnAoyrquyC5PuLuX+ 5NXocrhxwGVwILV+olrLFTJdymOr0E+VFz0CMYRWErXlQ02frj0qLGAZX53+as8+dDo7jL2UNeJyB LZTExosGQfw7PvQ6zz1HCxk/6AH1l3nqvICEm98zZJubPTAyIPokHq1mjIW05SrJ9dCcgPF0zyGWL 4Tz5Uy4RGstO8PAONqtCFLyK7xnPaF2cPBRsrBEdQBZjfyBTf79PMfRifmiEIRaOisareDN+bTr4x Hq740z6LDj5TNLhjCP0grhysORN9o9q9Qhxi0nPV9ITaBhiDdPVH3RFNnK73Y6Rx0n6KAM8VWGSpF ZJQ+SCag==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8nb-00EDzg-0P; Mon, 02 Oct 2023 02:36:43 +0000 Date: Mon, 2 Oct 2023 03:36:43 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 14/15] ovl_dentry_revalidate_common(): fetch inode once Message-ID: <20231002023643.GO3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> <20231002023613.GN3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002023613.GN3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org d_inode_rcu() is right - we might be in rcu pathwalk; however, OVL_E() hides plain d_inode() on the same dentry... Signed-off-by: Al Viro Reviewed-by: Amir Goldstein --- fs/overlayfs/super.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index f09184b865ec..905d3aaf4e55 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -104,8 +104,8 @@ static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak) static int ovl_dentry_revalidate_common(struct dentry *dentry, unsigned int flags, bool weak) { - struct ovl_entry *oe = OVL_E(dentry); - struct ovl_path *lowerstack = ovl_lowerstack(oe); + struct ovl_entry *oe; + struct ovl_path *lowerstack; struct inode *inode = d_inode_rcu(dentry); struct dentry *upper; unsigned int i; @@ -115,6 +115,8 @@ static int ovl_dentry_revalidate_common(struct dentry *dentry, if (!inode) return -ECHILD; + oe = OVL_I_E(inode); + lowerstack = ovl_lowerstack(oe); upper = ovl_i_dentry_upper(inode); if (upper) ret = ovl_revalidate_real(upper, flags, weak); From patchwork Mon Oct 2 02:37:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 13405519 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D19C2E784A7 for ; Mon, 2 Oct 2023 02:37:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229990AbjJBChQ (ORCPT ); Sun, 1 Oct 2023 22:37:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229935AbjJBChP (ORCPT ); Sun, 1 Oct 2023 22:37:15 -0400 Received: from zeniv.linux.org.uk (zeniv.linux.org.uk [IPv6:2a03:a000:7:0:5054:ff:fe1c:15ff]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33FC9C9 for ; Sun, 1 Oct 2023 19:37:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=linux.org.uk; s=zeniv-20220401; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=+qRw2nig3APcRxOSe394947Vm6w5yWReQ0ggdVYj3xA=; b=uA44cOVCuiHmIhoWPPIJwrAgeG VehtUOPWTC+Vkbqt8BJinaG7VnvGv3D1BgZEheAHUrkw+AMgpWaFuAHm599AILmROC+Z7n2vLJNVg Xam224y9QIdlkC8SXeAFYB2GDyo6ESKxxHxZWvXvRRqerf9HmfbJkrx6CdU1AmRn85cdj7I5++y3e jyTuQbTUV3ccliXLckGtGBmTZMxjLl94B3+kiF1wvKpsPzceWCKvMJHT82Y9uWhUQTBMHAqg6igde Zb56D7MbOdYf//sHcrvft2djsXCPpKmXOiP0ZmX8k9bpdkiPumQGlAJTwqx8FpGNjYRONz1wMEXN2 A2bt5A5Q==; Received: from viro by zeniv.linux.org.uk with local (Exim 4.96 #2 (Red Hat Linux)) id 1qn8o3-00EE0M-0r; Mon, 02 Oct 2023 02:37:11 +0000 Date: Mon, 2 Oct 2023 03:37:11 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Christian Brauner , Christoph Hellwig , Linus Torvalds , Namjae Jeon , David Sterba , David Howells , Miklos Szeredi , Amir Goldstein , Trond Myklebust , Bob Peterson , Steve French , Luis Chamberlain Subject: [PATCH 15/15] overlayfs: make use of ->layers safe in rcu pathwalk Message-ID: <20231002023711.GP3389589@ZenIV> References: <20231002022815.GQ800259@ZenIV> <20231002022846.GA3389589@ZenIV> <20231002023613.GN3389589@ZenIV> <20231002023643.GO3389589@ZenIV> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20231002023643.GO3389589@ZenIV> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org ovl_permission() accesses ->layers[...].mnt; we can't have ->layers freed without an RCU delay on fs shutdown. Fortunately, kern_unmount_array() used to drop those mounts does include an RCU delay, so freeing is delayed; unfortunately, the array passed to kern_unmount_array() is formed by mangling ->layers contents and that happens without any delays. Use a separate array instead; local if we have a few layers, kmalloc'ed if there's a lot of them. If allocation fails, fall back to kern_unmount() for individual mounts; it's not a fast path by any stretch of imagination. Signed-off-by: Al Viro --- fs/overlayfs/ovl_entry.h | 1 - fs/overlayfs/params.c | 26 ++++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h index e9539f98e86a..618b63bb7987 100644 --- a/fs/overlayfs/ovl_entry.h +++ b/fs/overlayfs/ovl_entry.h @@ -30,7 +30,6 @@ struct ovl_sb { }; struct ovl_layer { - /* ovl_free_fs() relies on @mnt being the first member! */ struct vfsmount *mnt; /* Trap in ovl inode cache */ struct inode *trap; diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index b9355bb6d75a..ab594fd407b4 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -738,8 +738,15 @@ int ovl_init_fs_context(struct fs_context *fc) void ovl_free_fs(struct ovl_fs *ofs) { struct vfsmount **mounts; + struct vfsmount *m[16]; + unsigned n = ofs->numlayer; unsigned i; + if (n > 16) + mounts = kmalloc_array(n, sizeof(struct mount *), GFP_KERNEL); + else + mounts = m; + iput(ofs->workbasedir_trap); iput(ofs->indexdir_trap); iput(ofs->workdir_trap); @@ -752,14 +759,21 @@ void ovl_free_fs(struct ovl_fs *ofs) if (ofs->upperdir_locked) ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root); - /* Hack! Reuse ofs->layers as a vfsmount array before freeing it */ - mounts = (struct vfsmount **) ofs->layers; - for (i = 0; i < ofs->numlayer; i++) { + for (i = 0; i < n; i++) { iput(ofs->layers[i].trap); - mounts[i] = ofs->layers[i].mnt; - kfree(ofs->layers[i].name); + if (unlikely(!mounts)) + kern_unmount(ofs->layers[i].mnt); + else + mounts[i] = ofs->layers[i].mnt; } - kern_unmount_array(mounts, ofs->numlayer); + if (mounts) { + kern_unmount_array(mounts, n); + if (mounts != m) + kfree(mounts); + } + // by this point we had an RCU delay from kern_unmount{_array,}() + for (i = 0; i < n; i++) + kfree(ofs->layers[i].name); kfree(ofs->layers); for (i = 0; i < ofs->numfs; i++) free_anon_bdev(ofs->fs[i].pseudo_dev);