From: Greg KH <gregkh@linuxfoundation.org>
To: Christian Brauner <brauner@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Christoph Hellwig <hch@lst.de>,
Florian Weimer <fweimer@redhat.com>,
Aleksa Sarai <cyphar@cyphar.com>,
linux-fsdevel@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk>,
stable@vger.kernel.org
Subject: Re: [PATCH] attr: block mode changes of symlinks
Date: Wed, 12 Jul 2023 18:21:51 +0200 [thread overview]
Message-ID: <2023071228-puppet-regalia-484f@gregkh> (raw)
In-Reply-To: <20230712-vfs-chmod-symlinks-v1-1-27921df6011f@kernel.org>
On Wed, Jul 12, 2023 at 11:56:35AM +0200, Christian Brauner wrote:
> Changing the mode of symlinks is meaningless as the vfs doesn't take the
> mode of a symlink into account during path lookup permission checking.
>
> However, the vfs doesn't block mode changes on symlinks. This however,
> has lead to an untenable mess roughly classifiable into the following
> two categories:
>
> (1) Filesystems that don't implement a i_op->setattr() for symlinks.
>
> Such filesystems may or may not know that without i_op->setattr()
> defined, notify_change() falls back to simple_setattr() causing the
> inode's mode in the inode cache to be changed.
>
> That's a generic issue as this will affect all non-size changing
> inode attributes including ownership changes.
>
> Example: afs
>
> (2) Filesystems that fail with EOPNOTSUPP but change the mode of the
> symlink nonetheless.
>
> Some filesystems will happily update the mode of a symlink but still
> return EOPNOTSUPP. This is the biggest source of confusion for
> userspace.
>
> The EOPNOTSUPP in this case comes from POSIX ACLs. Specifically it
> comes from filesystems that call posix_acl_chmod(), e.g., btrfs via
>
> if (!err && attr->ia_valid & ATTR_MODE)
> err = posix_acl_chmod(idmap, dentry, inode->i_mode);
>
> Filesystems including btrfs don't implement i_op->set_acl() so
> posix_acl_chmod() will report EOPNOTSUPP.
>
> When posix_acl_chmod() is called, most filesystems will have
> finished updating the inode.
>
> Perversely, this has the consequences that this behavior may depend
> on two kconfig options and mount options:
>
> * CONFIG_POSIX_ACL={y,n}
> * CONFIG_${FSTYPE}_POSIX_ACL={y,n}
> * Opt_acl, Opt_noacl
>
> Example: btrfs, ext4, xfs
>
> The only way to change the mode on a symlink currently involves abusing
> an O_PATH file descriptor in the following manner:
>
> fd = openat(-1, "/path/to/link", O_CLOEXEC | O_PATH | O_NOFOLLOW);
>
> char path[PATH_MAX];
> snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
> chmod(path, 0000);
>
> But for most major filesystems with POSIX ACL support such as btrfs,
> ext4, ceph, tmpfs, xfs and others this will fail with EOPNOTSUPP with
> the mode still updated due to the aforementioned posix_acl_chmod()
> nonsense.
>
> So, given that for all major filesystems this would fail with EOPNOTSUPP
> and that both glibc (cf. [1]) and musl (cf. [2]) outright block mode
> changes on symlinks we should just try and block mode changes on
> symlinks directly in the vfs and have a clean break with this nonsense.
>
> If this causes any regressions, we do the next best thing and fix up all
> filesystems that do return EOPNOTSUPP with the mode updated to not call
> posix_acl_chmod() on symlinks.
>
> But as usual, let's try the clean cut solution first. It's a simple
> patch that can be easily reverted. Not marking this for backport as I'll
> do that manually if we're reasonably sure that this works and there are
> no strong objections.
>
> We could block this in chmod_common() but it's more appropriate to do it
> notify_change() as it will also mean that we catch filesystems that
> change symlink permissions explicitly or accidently.
>
> Similar proposals were floated in the past as in [3] and [4] and again
> recently in [5]. There's also a couple of bugs about this inconsistency
> as in [6] and [7].
>
> Link: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/fchmodat.c;h=99527a3727e44cb8661ee1f743068f108ec93979;hb=HEAD [1]
> Link: https://git.musl-libc.org/cgit/musl/tree/src/stat/fchmodat.c [2]
> Link: https://lore.kernel.org/all/20200911065733.GA31579@infradead.org [3]
> Link: https://sourceware.org/legacy-ml/libc-alpha/2020-02/msg00518.html [4]
> Link: https://lore.kernel.org/lkml/87lefmbppo.fsf@oldenburg.str.redhat.com [5]
> Link: https://sourceware.org/legacy-ml/libc-alpha/2020-02/msg00467.html [6]
> Link: https://sourceware.org/bugzilla/show_bug.cgi?id=14578#c17 [7]
> Cc: stable@vger.kernel.org # no backport before v6.6-rc2 is tagged
How far back should this go?
thanks,
greg k-h
next prev parent reply other threads:[~2023-07-12 16:23 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-12 9:56 [PATCH] attr: block mode changes of symlinks Christian Brauner
2023-07-12 16:21 ` Greg KH [this message]
2023-07-12 17:58 ` Christian Brauner
2023-07-12 16:24 ` Linus Torvalds
2023-07-12 17:56 ` Christian Brauner
-- strict thread matches above, loose matches on Subject: below --
2023-10-18 18:34 Jesse Hathaway
2023-10-18 18:40 ` Greg KH
2023-10-18 18:49 ` Jesse Hathaway
2023-10-18 19:09 ` Greg KH
2023-10-20 8:34 ` Linux regression tracking (Thorsten Leemhuis)
2023-10-20 11:01 ` Christian Brauner
2023-10-20 13:26 ` Giuseppe Scrivano
2023-10-20 14:25 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2023071228-puppet-regalia-484f@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=brauner@kernel.org \
--cc=cyphar@cyphar.com \
--cc=fweimer@redhat.com \
--cc=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.