Re: [PATCH] ovl: Reject mounting case-insensitive filesystems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Dec 23, 2023 at 6:23 AM Gabriel Krisman Bertazi <krisman@xxxxxxx> wrote:
>
> Eric Biggers <ebiggers@xxxxxxxxxx> writes:
>
> > On Fri, Dec 15, 2023 at 04:16:00PM -0500, Gabriel Krisman Bertazi wrote:
> >> [Apologies for the quick spin of a v2.  The only difference are a couple
> >> fixes to the build when CONFIG_UNICODE=n caught by LKP and detailed in
> >> each patch changelog.]
> >>
> >> When case-insensitive and fscrypt were adapted to work together, we moved the
> >> code that sets the dentry operations for case-insensitive dentries(d_hash and
> >> d_compare) to happen from a helper inside ->lookup.  This is because fscrypt
> >> wants to set d_revalidate only on some dentries, so it does it only for them in
> >> d_revalidate.
> >>
> >> But, case-insensitive hooks are actually set on all dentries in the filesystem,
> >> so the natural place to do it is through s_d_op and let d_alloc handle it [1].
> >> In addition, doing it inside the ->lookup is a problem for case-insensitive
> >> dentries that are not created through ->lookup, like those coming
> >> open-by-fhandle[2], which will not see the required d_ops.
> >>
> >> This patchset therefore reverts to using sb->s_d_op to set the dentry operations
> >> for case-insensitive filesystems.  In order to set case-insensitive hooks early
> >> and not require every dentry to have d_revalidate in case-insensitive
> >> filesystems, it introduces a patch suggested by Al Viro to disable d_revalidate
> >> on some dentries on the fly.
> >>
> >> It survives fstests encrypt and quick groups without regressions.  Based on
> >> v6.7-rc1.
> >>
> >> [1] https://lore.kernel.org/linux-fsdevel/20231123195327.GP38156@ZenIV/
> >> [2] https://lore.kernel.org/linux-fsdevel/20231123171255.GN38156@ZenIV/
> >>
> >> Gabriel Krisman Bertazi (8):
> >>   dcache: Add helper to disable d_revalidate for a specific dentry
> >>   fscrypt: Drop d_revalidate if key is available
> >>   libfs: Merge encrypted_ci_dentry_ops and ci_dentry_ops
> >>   libfs: Expose generic_ci_dentry_ops outside of libfs
> >>   ext4: Set the case-insensitive dentry operations through ->s_d_op
> >>   f2fs: Set the case-insensitive dentry operations through ->s_d_op
> >>   libfs: Don't support setting casefold operations during lookup
> >>   fscrypt: Move d_revalidate configuration back into fscrypt
> >
> > Thanks Gabriel, this series looks good.  Sorry that we missed this when adding
> > the support for encrypt+casefold.
> >
> > It's slightly awkward that some lines of code added by patches 5-6 are removed
> > in patch 8.  These changes look very hard to split up, though, so you've
> > probably done about the best that can be done.
> >
> > One question/request: besides performance, the other reason we're so careful
> > about minimizing when ->d_revalidate is set for fscrypt is so that overlayfs
> > works on encrypted directories.  This is because overlayfs is not compatible
> > with ->d_revalidate.  I think your solution still works for that, since
> > DCACHE_OP_REVALIDATE will be cleared after the first call to
> > fscrypt_d_revalidate(), and when checking for usupported dentries overlayfs does
> > indeed check for DCACHE_OP_REVALIDATE instead of ->d_revalidate directly.
> > However, that does rely on that very first call to ->d_revalidate actually
> > happening before the check is done.  It would be nice to verify that
> > overlayfs+fscrypt indeed continues to work, and explicitly mention this
> > somewhere (I don't see any mention of overlayfs+fscrypt in the series).
>
> Hi Eric,
>
> From my testing, overlayfs+fscrypt should work fine.  I tried mounting
> it on top of encrypted directories, with and without key, and will add
> this information to the commit message.  If we adopt the suggestion from
> Al in the other subthread, even better, we won't need the first
> d_revalidate to happen before the check, so I'll adopt that.
>
> While looking into overlayfs, I found another reason we would need this
> patchset.  A side effect of not configuring ->d_op through s_d_op is
> that the root dentry won't have d_op set.  While this is fine for
> casefold, because we forbid the root directory from being
> case-insensitive, we can trick overlayfs into mounting a
> filesystem it can't handle.
>
> Even with this merged, and as Christian said in another thread regarding
> ecryptfs, we should handle this explicitly.  Something like below.
>
> Amir, would you consider this for -rc8?

IIUC, this fixes a regression from v5.10 with a very low likelihood of
impact on anyone in the real world, so what's the rush?
I would rather that you send this fix along with your patch set.

Feel free to add:

Acked-by: Amir Goldstein <amir73il@xxxxxxxxx>

after fixing nits below

>
> -- >8 --
> Subject: [PATCH] ovl: Reject mounting case-insensitive filesystems
>
> overlayfs relies on the filesystem setting DCACHE_OP_HASH or
> DCACHE_OP_COMPARE to reject mounting over case-insensitive directories.
>
> Since commit bb9cd9106b22 ("fscrypt: Have filesystems handle their
> d_ops"), we set ->d_op through a hook in ->d_lookup, which
> means the root dentry won't have them, causing the mount to accidentally
> succeed.
>
> In v6.7-rc7, the following sequence will succeed to mount, but any
> dentry other than the root dentry will be a "weird" dentry to ovl and
> fail with EREMOTE.
>
>   mkfs.ext4 -O casefold lower.img
>   mount -O loop lower.img lower
>   mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work ovl /mnt
>
> Mounting on a subdirectory fails, as expected, because DCACHE_OP_HASH
> and DCACHE_OP_COMPARE are properly set by ->lookup.
>
> Fix by explicitly rejecting superblocks that allow case-insensitive
> dentries.
>
> Fixes: bb9cd9106b22 ("fscrypt: Have filesystems handle their d_ops")
> Signed-off-by: Gabriel Krisman Bertazi <krisman@xxxxxxx>
> ---
>  fs/overlayfs/params.c | 2 ++
>  include/linux/fs.h    | 9 +++++++++
>  2 files changed, 11 insertions(+)
>
> diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c
> index 3fe2dde1598f..99495f079644 100644
> --- a/fs/overlayfs/params.c
> +++ b/fs/overlayfs/params.c
> @@ -286,6 +286,8 @@ static int ovl_mount_dir_check(struct fs_context *fc, const struct path *path,
>         if (!d_is_dir(path->dentry))
>                 return invalfc(fc, "%s is not a directory", name);
>

Please add a comment to explain why this is needed to prevent post
mount lookup failures.

> +       if (sb_has_encoding(path->mnt->mnt_sb))
> +               return invalfc(fc, "caseless filesystem on %s not supported", name);
>

I have not seen you use the term "caseless" on the list since 2018. old habits?
Please use the term "case-insensitive" and please move the
ovl_dentry_weird() check
below this one, because when trying to mount overlayfs over non-root
case-insensitive
directory, the more specific error message is more useful.

Thanks,
Amir.





[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux