Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp1073268pxv; Fri, 16 Jul 2021 00:38:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz4A0mAkVHer04rB/v1LJBfNWzEE6i2vg7m6h3PPHGzgsO5TJ2tU8LSFjJAq5pHkbuLN7DP X-Received: by 2002:a02:666d:: with SMTP id l45mr8064184jaf.0.1626421085286; Fri, 16 Jul 2021 00:38:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626421085; cv=none; d=google.com; s=arc-20160816; b=mHHBeFHivNu2bvdMhGlZCpK2GVhZ70FUvkDXM7IrqvDnn+Ce9VUN2TvkAzfCMnDbrT +VI4539J9sRsmqS1rNZAskuj5gyyNMzAnIOktQrCY4D2bzzbRDPJ8crD9sWjhq6DDSKl x9TpKyVpzMlNb6pufh9E6MN9nsqCkxqeX2CLMf5TF2O6s18Usg9Kdq2bgPp4nhTKIuf5 YLkFdq4J21J3P01/x5zsOok6RD8rIx03U/hTjJWwxTYfUzBeUDTiTkMZr5rMSk0GDQ2E Szf35Ru178z5g5peczkGwjuTLlxVzy+siQvHab9dALD2TPOH8F2Km0wIimy6PPKpneGN gKlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:dkim-signature:from; bh=opRZsSEeku957DevQAtKUWWxB35MR5mNmlErHsKHw+E=; b=UbSXHomhGYVXSdNooJNOOelI+JD4czdPE4W2oJxX/hFaV4hy5UDxXAU0s0jsT5MONw UpofM85D56MoobH6iIlChsDLUSFiOtnM5qQ963ONnWPgh/I/3RiUw5lB8uhihQFJ1NrQ qL6vjOL0KFG7TAs+2XVRi8KKdu4g0PQ46ixKRhgUI7QjIw70+HStWg//9F9jpY3oBapd gGDvruanS5wsnneq6DXaSQ72QJTh33s4gdrY5I7jFtc4Du7YJFVJGtXDdAnjDjo4rpcJ oOCDhQyF7D60xaunC0ZdTniqBfaq1WJEXHcAQpXbvA9MlvcnrejXKn+yg9K4vABWx90z ZppA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@synology.com header.s=123 header.b=Mm8nXgrT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=synology.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z13si8737750ile.110.2021.07.16.00.37.53; Fri, 16 Jul 2021 00:38:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@synology.com header.s=123 header.b=Mm8nXgrT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=synology.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236612AbhGPHjk (ORCPT + 99 others); Fri, 16 Jul 2021 03:39:40 -0400 Received: from mail.synology.com ([211.23.38.101]:48874 "EHLO synology.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S236603AbhGPHjd (ORCPT ); Fri, 16 Jul 2021 03:39:33 -0400 From: Chung-Chiang Cheng DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synology.com; s=123; t=1626420997; bh=KK6YlVgVAQfJEYMeRt+KgwyuMZzCVXDQfwETpiRmEnM=; h=From:To:Cc:Subject:Date; b=Mm8nXgrTXGx3x4EDrZUPsxcvl75IENzS0hA3uzBA32dQi5MbRNGMwV8HuSmO/3kI8 K8HI4YoxQV3Osc5etdZabLNKm+dVarfRWxHv8tiUjUj1T8w07rrvLL1S3qGt1obIKq p7YgVHhNoiqAJhASxx1gHzyfeKYayqW8FlrIYnpY= To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, slava@dubeyko.com, gustavoars@kernel.org, gregkh@linuxfoundation.org, keescook@chromium.org, mszeredi@redhat.com Cc: Chung-Chiang Cheng Subject: [RESEND PATCH v2] hfsplus: prevent negative dentries when casefolded Date: Fri, 16 Jul 2021 15:36:35 +0800 Message-Id: <20210716073635.1613671-1-cccheng@synology.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Synology-MCP-Status: no X-Synology-Spam-Flag: no X-Synology-Spam-Status: score=0, required 6, WHITELIST_FROM_ADDRESS 0 X-Synology-Virus-Status: no Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org hfsplus uses the case-insensitive filenames by default, but VFS negative dentries are incompatible with case-insensitive. For example, the following instructions will get a cached filename 'aaa' which isn't expected. There is no such problem in macOS. touch aaa rm aaa touch AAA This patch takes the same approach to drop negative dentires as vfat does. The dentry is revalidated without blocking and storing to the dentry, and should be safe in rcu-walk. Signed-off-by: Chung-Chiang Cheng --- fs/hfsplus/hfsplus_fs.h | 1 + fs/hfsplus/inode.c | 1 + fs/hfsplus/unicode.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 1798949f269b..4ae7f1ca1584 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -520,6 +520,7 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str); int hfsplus_compare_dentry(const struct dentry *dentry, unsigned int len, const char *str, const struct qstr *name); +int hfsplus_revalidate_dentry(struct dentry *dentry, unsigned int flags); /* wrapper.c */ int hfsplus_submit_bio(struct super_block *sb, sector_t sector, void *buf, diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 6fef67c2a9f0..4188a0760118 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -179,6 +179,7 @@ const struct address_space_operations hfsplus_aops = { const struct dentry_operations hfsplus_dentry_operations = { .d_hash = hfsplus_hash_dentry, .d_compare = hfsplus_compare_dentry, + .d_revalidate = hfsplus_revalidate_dentry, }; static void hfsplus_get_perms(struct inode *inode, diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index 73342c925a4b..e336631334eb 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c @@ -10,6 +10,7 @@ */ #include +#include #include #include "hfsplus_fs.h" #include "hfsplus_raw.h" @@ -518,3 +519,34 @@ int hfsplus_compare_dentry(const struct dentry *dentry, return 1; return 0; } + +int hfsplus_revalidate_dentry(struct dentry *dentry, unsigned int flags) +{ + /* + * dentries are always valid when disabling casefold. + */ + if (!test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(dentry->d_sb)->flags)) + return 1; + + /* + * Positive dentries are valid when enabling casefold. + * + * Note, rename() to existing directory entry will have ->d_inode, and + * will use existing name which isn't specified name by user. + * + * We may be able to drop this positive dentry here. But dropping + * positive dentry isn't good idea. So it's unsupported like + * rename("filename", "FILENAME") for now. + */ + if (d_really_is_positive(dentry)) + return 1; + + /* + * Drop the negative dentry, in order to make sure to use the case + * sensitive name which is specified by user if this is for creation. + */ + if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) + return 0; + + return 1; +} -- 2.25.1