GNU bug report logs -
#70214
'install' fails to copy regular file to autofs/cifs, due to ACL or xattr handling
Previous Next
Full log
Message #8 received at 70214 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 05/04/2024 10:48, Bruno Haible wrote:
> Hi,
>
> The 'install' program from coreutils-9.5 fails to copy a regular file
> from an ext4 mount to an autofs/cifs mount.
>
> The same operation, with 'cp -a', works fine.
>
> Also, it works fine when coreutils was built with the configure options
> "--disable-acl --disable-xattr".
>
> How to reproduce
> ================
>
> 1) On the machine sparcdev.matoro.tk (Linux 6.8.2), I built coreutils-9.5
> from source,
> - once with default options, in build-sparc64/,
> - once with "--disable-acl --disable-xattr", in build-sparc64-no-acl/.
>
> 2) Create a regular file on an ext4 mount:
>
> $ echo hi > /var/tmp/foo3941
> $ ls -lZ /var/tmp/foo3941
> -rw-r----- 1 g-haible g-haible ? 3 Apr 4 13:29 /var/tmp/foo3941
> $ getfacl /var/tmp/foo3941
> getfacl: Removing leading '/' from absolute path names
> # file: var/tmp/foo3941
> # owner: g-haible
> # group: g-haible
> user::rw-
> group::r--
> other::---
> $ df -m /var/tmp/
> Filesystem 1M-blocks Used Available Use% Mounted on
> /dev/root 560245 123140 408574 24% /
> $ mount | grep ' / '
> /dev/sda2 on / type ext4 (rw,noatime)
>
> 3) Details about the destination directory:
>
> $ echo $HOME
> /media/guest-homedirs/haible
> $ mount | grep /media/guest-homedirs/haible
> /etc/autofs/auto.guest-homedirs on /media/guest-homedirs/haible type autofs (rw,relatime,fd=7,pgrp=2325,timeout=60,minproto=5,maxproto=5,direct,pipe_ino=46092)
> //syslog.matoro.tk/guest-haible on /media/guest-homedirs/haible type cifs (rw,nosuid,relatime,vers=1.0,cache=strict,username=nobody,uid=30014,forceuid,gid=30014,forcegid,addr=fd05:0000:0000:0000:0000:0000:0000:0001,soft,unix,posixpaths,serverino,mapposix,acl,rsize=1048576,wsize=65536,bsize=1048576,retrans=1,echo_interval=60,actimeo=1,closetimeo=1)
>
> 4) The operation that fails:
>
> $ build-sparc64/src/ginstall -c /var/tmp/foo3941 $HOME/foo3941; echo $?
> build-sparc64/src/ginstall: setting permissions for '/media/guest-homedirs/haible/foo3941': Permission denied
> 1
> $ build-sparc64-no-acl/src/ginstall -c /var/tmp/foo3941 $HOME/foo3941; echo $?
> 0
>
> 5) The same thing with 'cp -a' succeeds:
>
> $ build-sparc64/src/cp -a /var/tmp/foo3941 $HOME/foo3941; echo $?
> 0
> $ build-sparc64-no-acl/src/cp -a /var/tmp/foo3941 $HOME/foo3941; echo $?
> 0
>
> 6) 'strace' shows a failing call to fsetxattr:
>
> $ strace build-sparc64/src/ginstall -c /var/tmp/foo3941 $HOME/foo3941
> fsetxattr(4, "system.posix_acl_access", "\2\0\0\0\1\0\6\0\377\377\377\377\4\0\0\0\377\377\377\377 \0\0\0\377\377\377\377", 28, 0) = -1 EACCES (Permission denied)
> fchmod(4, 0600) = 0
> Notes
> =====
>
> The 'cp' program does *not* use fsetxattr() calls on the destination file
> descriptor and therefore does not fail:
>
> $ strace build-sparc64/src/cp -a /var/tmp/foo3941 $HOME/foo3941
> flistxattr(3, NULL, 0) = 0
> flistxattr(3, 0x7feff9860a0, 0) = 0
> fchmod(4, 0100640) = 0
> flistxattr(3, NULL, 0) = 0
> flistxattr(3, 0x7feff9860c0, 0) = 0
> As you can see, it uses 4 flistxattr() calls on the source file descriptor,
> apparently detecting that it's a regular file without ACLs, and proceeds to
> do a simple fchmod() call on the destination file descriptor.
>
> Probably the same logic is needed in the 'install' program.
install(1) defaults to mode 600 for new files, and uses set_acl() with that
(since 2007 https://github.com/coreutils/coreutils/commit/f634e8844 )
The psuedo code that install(1) uses is:
copy_reg()
if (x->set_mode) /* install */
set_acl(dest, x->mode /* 600 */)
ctx->acl = acl_from_mode ( /* 600 */)
acl_set_fd (ctx->acl) /* fails EACCES */
if (! acls_set)
must_chmod = true;
if (must_chmod)
saved_errno = EACCES;
chmod (ctx->mode /* 600 */)
if (save_errno)
return -1;
This issue only only seems to be on CIFS.
I'm seeing lot of weird behavior with ACLs there:
acl_set_fd (acl_from_mode (600)) -> EACCES
acl_set_fd (acl_from_mode (755)) -> EINVAL
getxattr ("system.posix_acl_access") -> EOPNOTSUPP
Note we ignore EINVAL and EOPNOTSUPP errors in set_acl(),
and it's just the EACCES that's problematic.
Note this is quite similar to https://debbugs.gnu.org/65599
where Paul also noticed EACCES with fsetxattr() (and others) on CIFS.
The attached is a potential solution which I tested as working
on the same matoro system that Bruno used.
I think I'll apply that after thinking a bit more about it.
cheers,
Pádraig.
[gnulib-set-acl-cifs.patch (text/x-patch, attachment)]
This bug report was last modified 1 year and 39 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.