X-Debbugs-CC: Daniel Lewart <lewa...@gmail.com>, Steve McIntyre 
<st...@einval.com>

Dear Maintainer,

It seems that this bug now affects ls and stat (in unstable).
I suspect that it was the cause of the recent failures of
debian-installer daily builds [1], [2].

How to reproduce the symptoms :

$ fakeroot
# touch file1
# mknod null c 1 3
# ls -ln
total 0
-rw------- 1 1000 1000 0 Jul 27 10:55 file1
-rw------- 1 1000 1000 0 Jul 27 10:55 null
# file null
null: character special (1/3)
# stat *
  File: file1
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 822h/2082d      Inode: 136799      Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/     me)   Gid: ( 1000/     me)
Access: 2020-07-27 10:55:12.326299207 +0000
Modify: 2020-07-27 10:55:12.326299207 +0000
Change: 2020-07-27 10:55:12.326299207 +0000
 Birth: -
  File: null
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 822h/2082d      Inode: 136801      Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/     me)   Gid: ( 1000/     me)
Access: 2020-07-27 10:55:48.486478516 +0000
Modify: 2020-07-27 10:55:48.486478516 +0000
Change: 2020-07-27 10:55:48.486478516 +0000

I tested the small wrapper below to confirm that statx is indeed the culprit :

$ gcc -c -fPIC fake_statx_diagnostic.c
$ gcc -shared -Wl,-soname,libfakestatx.so.0 -o libfakestatx.so.0.0 
fake_statx_diagnostic.o -lc
$ export LD_LIBRARY_PATH=$(readlink -f .)
$ export LD_PRELOAD=libfakestatx.so.0.0
$ fakeroot
# touch file2
# ls -ln file2
-rw------- 1 0 0 0 Jul 27 12:46 file2
# mknod null c 1 3
# ls -ln null
crw------- 1 0 0 1, 3 Jul 27 12:46 null
# stat *
  File: file2
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 822h/2082d      Inode: 148745      Links: 1
Access: (0600/-rw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-07-27 12:46:12.971327563 +0000
Modify: 2020-07-27 12:46:12.971327563 +0000
Change: 2020-07-27 12:46:12.971327563 +0000
 Birth: -
  File: null
  Size: 0               Blocks: 0          IO Block: 4096   character special 
file
Device: 822h/2082d      Inode: 148748      Links: 1     Device type: 1,3
Access: (0600/crw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-07-27 12:46:51.915520676 +0000
Modify: 2020-07-27 12:46:51.915520676 +0000
Change: 2020-07-27 12:46:51.915520676 +0000
 Birth: -

which is the expected result.

I hope it will help ! Thank you for your work on fakeroot.

Regards,
JH Chatenet

[1]: https://lists.debian.org/debian-cd/2020/07/msg00045.htm
[2]: https://lists.debian.org/debian-cd/2020/07/msg00046.html

$ dpkg -l fakeroot coreutils libc6
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-========================================
ii  coreutils      8.32-3       i386         GNU core utilities
ii  fakeroot       1.24-1       i386         tool for simulating superuser 
privileges
ii  libc6:i386     2.31-2       i386         GNU C Library: Shared libraries


----------8<-----fake_statx_diagnostic.c----------8<----------------
/* A simple wrapper of statx : just for test ! */

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>           /* Definition of AT_* constants */

#include <dlfcn.h>

#include <sys/sysmacros.h>

int statx(int dirfd, const char *pathname, int flags,
                 unsigned int mask, struct statx *statxbuf) {

        int ret;
        struct stat sb;
        int (*next_statx)(int, const char*, int,
                 unsigned int, struct statx *);

        /* Retrieve the faked uid, gid and file type */

        ret = fstatat(dirfd, pathname, &sb, flags);

        if (ret)
                return(ret);

        /* Call the real statx */

        next_statx = dlsym(RTLD_NEXT, "statx");

        if (next_statx == NULL)
                return(-1);

        ret = next_statx(dirfd, pathname, flags, mask, statxbuf);

        if (ret)
                return(ret);


        /* Overwrite the real uid, gid and file type */

        statxbuf->stx_uid = sb.st_uid;
        statxbuf->stx_gid = sb.st_gid;
        statxbuf->stx_mode = sb.st_mode;

        statxbuf->stx_rdev_major = major(sb.st_rdev);
        statxbuf->stx_rdev_minor = minor(sb.st_rdev);

        return(ret);
}
----------8<-----fake_statx_diagnostic.c----------8<----------------

Reply via email to