From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Florian Weimer <fw@deneb.enyo.de>
Cc: linux-xfs@vger.kernel.org, libc-alpha@sourceware.org,
linux-fsdevel@vger.kernel.org
Subject: Re: XFS reports lchmod failure, but changes file system contents
Date: Wed, 12 Feb 2020 08:16:04 -0800 [thread overview]
Message-ID: <20200212161604.GP6870@magnolia> (raw)
In-Reply-To: <874kvwowke.fsf@mid.deneb.enyo.de>
On Wed, Feb 12, 2020 at 12:48:49PM +0100, Florian Weimer wrote:
> In principle, Linux supports lchmod via O_PATH descriptors and chmod
> on /proc/self/fd. (lchmod is the non-symbolic-link-following variant
> of chmod.)
>
> This helper program can be used to do this:
>
> #define _GNU_SOURCE
> #include <err.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/stat.h>
> #include <unistd.h>
>
> int
> main (int argc, char **argv)
> {
> if (argc != 3)
> {
> fprintf (stderr, "usage: %s MODE FILE\n", argv[0]);
> return 2;
> }
>
> unsigned int mode;
> if (sscanf (argv[1], "%o", &mode) != 1
> || mode != (mode_t) mode)
> errx (1, "invalid mode: %s", argv[1]);
>
> int fd = open (argv[2], O_PATH | O_NOFOLLOW);
> if (fd < 0)
> err (1, "open");
>
> char *fd_path;
> if (asprintf (&fd_path, "/proc/self/fd/%d", fd) < 0)
> err (1, "asprintf");
>
> if (chmod (fd_path, mode) != 0)
> err (1, "chmod");
>
> free (fd_path);
> if (close (fd) != 0)
> err (1, "close");
>
> return 0;
> }
>
> When changing the permissions of on XFS in this way, the chmod
> operation fails:
>
> $ ln -s does-not-exist /var/tmp/symlink
> $ ls -l /var/tmp/symlink
> lrwxrwxrwx. 1 fweimer fweimer 14 Feb 12 12:41 /var/tmp/symlink -> does-not-exist
> $ strace ./lchmod 0 /var/tmp/symlink
> […]
> openat(AT_FDCWD, "/var/tmp/symlink", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
> […]
> chmod("/proc/self/fd/3", 000) = -1 EOPNOTSUPP (Operation not supported)
> write(2, "lchmod: ", 8lchmod: ) = 8
> write(2, "chmod", 5chmod) = 5
> write(2, ": Operation not supported\n", 26: Operation not supported
> ) = 26
> exit_group(1) = ?
>
> But the file system contents has changed nevertheless:
>
> $ ls -l /var/tmp/symlink
> l---------. 1 fweimer fweimer 14 Feb 12 12:41 /var/tmp/symlink -> does-not-exist
> $ echo 3 | sudo tee /proc/sys/vm/drop_caches
> $ ls -l /var/tmp/symlink
> l---------. 1 fweimer fweimer 14 Feb 12 12:41 /var/tmp/symlink -> does-not-exist
>
> This looks like an XFS bug to me. With tmpfs, the chmod succeeds and
> is reflected in the file system.
>
> This bug also affects regular files, not just symbolic links.
>
> It causes the io/tst-lchmod glibc test to fail (after it has been
> fixed, the in-tree version has another bug).
xfs_setattr_nonsize calls posix_acl_chmod which returns EOPNOTSUPP
because the xfs symlink inode_operations do not include a ->set_acl
pointer.
I /think/ that posix_acl_chmod code exists to enforce that the file mode
reflects any acl that might be set on the inode, but in this case the
inode is a symbolic link.
I don't remember off the top of my head if ACLs are supposed to apply to
symlinks, but what do you think about adding get_acl/set_acl pointers to
xfs_symlink_inode_operations and xfs_inline_symlink_inode_operations ?
--D
next prev parent reply other threads:[~2020-02-12 16:16 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-12 11:48 XFS reports lchmod failure, but changes file system contents Florian Weimer
2020-02-12 12:15 ` Florian Weimer
2020-02-12 16:16 ` Darrick J. Wong [this message]
2020-02-12 18:11 ` Christoph Hellwig
2020-02-12 18:37 ` Darrick J. Wong
2020-02-12 19:15 ` Florian Weimer
2020-02-12 19:51 ` Al Viro
2020-02-12 19:55 ` Rich Felker
2020-02-12 20:01 ` Florian Weimer
2020-02-12 20:17 ` Andreas Schwab
2020-02-12 20:19 ` Rich Felker
2020-02-12 20:26 ` Florian Weimer
2020-02-12 20:38 ` Rich Felker
2020-02-12 20:27 ` Al Viro
2020-02-12 20:36 ` Rich Felker
2020-02-12 20:18 ` Rich Felker
2020-02-12 20:38 ` Paul Eggert
2020-02-21 4:09 ` Aleksa Sarai
2020-02-21 5:02 ` Al Viro
2020-02-21 5:21 ` Aleksa Sarai
2020-02-12 18:50 ` Florian Weimer
2020-02-12 18:55 ` Christoph Hellwig
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=20200212161604.GP6870@magnolia \
--to=darrick.wong@oracle.com \
--cc=fw@deneb.enyo.de \
--cc=libc-alpha@sourceware.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/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.