Hi, Quoting Johannes Schauer Marin Rodrigues (2023-02-06 00:47:35) > since glibc 2.34 and coreutils 9.1, fakeroot fails to preserve ownership > information when running "cp -a" on a file owned by a user other than > root. On armel, armhf and i386 (our 32 bit arches), you can reproduce > this problem by running inside fakeroot: > > $ touch foo > $ chown 0:42 foo > $ ls -lha foo > $ cp -a foo bar > $ ls -lha bar" > > which will print this: > > -rw-r--r-- 1 root shadow 0 Feb 5 23:00 foo > -rw-r--r-- 1 root root 0 Feb 5 23:00 bar > > I submitted an improvement to the `cp-a` test which adds a check for the > ownership information in addition to the mode checks as a merge request > for that test here: > > https://salsa.debian.org/clint/fakeroot/-/merge_requests/19 > > Observe how the salsaci pipeline succeds for amd64 but fails on i386. > The reason is that on i386, fakeroot will not retain the ownership > information. > > A quick comparison of the strace output on arm64 (which does not have > this problem) and armhf (which does have this problem) shows that arm64 > calls fchown() while armhf calls fchown32() which is not wrapped by > fakeroot. Maybe that is the problem? > > This breaks my package mmdebstrap in a similar way as #1023286 did.
I have a little bit of more input. This is what "cp --preserve=ownership" does on amd64 (according to ltrace): open("bar", 2162688, 015412541474) = -1 __errno_location() = 0x7ff47c598398 fstatat(0xffffff9c, 0x7ffe6c2ac337, 0x7ffe6c2aae10, 0) = 0 open("foo", 0, 00) = 3 fstat(3, 0x7ffe6c2aafc0, 0, 0x7ff47c72ae51) = 0 openat(0xffffff9c, 0x7ffe6c2ac33b, 193, 384) = 4 __errno_location() = 0x7ff47c598398 ioctl(4, 1074041865, 0x3) = -1 fstat(4, 0x7ffe6c2aaf30, 0xffffffff, 0x7ff47c730bab) = 0 Okay, nothing to see here. This works, after all. On i386 it looks like this: open64("bar", 2162688, 012625311011) = -1 __errno_location() = 0xf7bf56bc __fstatat64_time64(-100, 0xff958337, 0xff957948, 0) = 0 open64("foo", 0, 00) = 3 __fstat64_time64(3, 0xff957a8c, 0xff957948, 0) = 0 openat64(-100, 0xff95833b, 193, 384) = 4 __errno_location() = 0xf7bf56bc __ioctl_time64(4, 0x40049409, 3, 1) = -1 __fstat64_time64(4, 0xff957a20, 0, 0) = 0 So now this looks even more like #1023286 because it involves __fstatat64_time64 and __fstat64_time64. I added this patch to fakeroot: --- a/libfakeroot.c +++ b/libfakeroot.c @@ -2671,6 +2673,11 @@ int WRAP_FSTATAT64_TIME64 FSTATAT64_TIME64_ARG(int ver, int r; +#ifdef LIBFAKEROOT_DEBUGGING + if (fakeroot_debug) { + fprintf(stderr, "fstatat64[time64] fd %d %s\n", dir_fd, path); + } +#endif /* LIBFAKEROOT_DEBUGGING */ r=NEXT_FSTATAT64_TIME64(ver, dir_fd, path, st, flags); if(r) return -1; And re-ran the t.cp-a test that I changed according to my merge request to reproduce the problem on i386 like this: env --chdir=test srcdir=$(pwd)/test VERBOSE=1 libfakeroot=libfakeroot-0.so sh -x ./t.cp-a (is there a better way to run individual tests with maximum verbosity?) The relevant call to `cp -a` looks like this: stat64 file_name /home/josch/usr/bin/cp stat64 file_name /usr/local/bin/cp stat64 file_name /usr/bin/cp fstatat64[time64] fd -100 empty load_library_symbols fstat64[time64] fd 3 fstat64[time64] fd 4 flistxattr fd 3 flistxattr fd 3 fchmod fd 4 This seems to indicate that __fstatat64_time64 does get wrapped as expected. The dirfd is set to -100 which is the special value AT_FDCWD. I'm at a loss at how to proceed. Can you find out more? Thanks! cheers, josch
signature.asc
Description: signature