retitle 473682 fakechroot does not properly wrap *at syscalls (openat, unlinkat, fstatat, etc) tags 473682 +patch thanks
I think i've narrowed down what's happening here. /bin/rm from coreutils 6.10 appears to use the new fstatat64() and unlinkat() system calls (they were added to the kernel in 2.6.16, according to the section 2 manpages). The NOTES section of openat(2) has the justification for these new syscalls, and path_resolution(7) offers more in-depth information. I needed to use the version of strace from unstable (4.5.15-1.2) to see a record of the *at syscalls -- the version in lenny at the moment (4.5.14-2) can't even identify them properly. It looks like /bin/rm is now unlinking files with an invocation like this: unlinkat(AT_FDCWD, "/tmp/cdtemp.E32444/x", 0) = 0 It appears that fakechroot just doesn't know about these system calls, and so doesn't wrap them properly. The patch below seems to fix /bin/rm for the test case i outlined above, but needs to be expanded to cover the other *at calls. I'm sure it also needs to be made more portable -- i just grepped "objdump -T /bin/rm" to figure out which flavor of fstatat64 i needed to support and kludged it up to create the patch. Please let me know if there's anything else i can do to get this change through. Without something like this, fakechroot won't let me debootstrap a lenny instance! Regards, --dkg --- ../libfakechroot.c.orig 2008-03-31 23:10:37.000000000 -0400 +++ src/libfakechroot.c 2008-04-01 00:11:29.000000000 -0400 @@ -463,6 +463,8 @@ static int (*next_truncate64) (const char *path, off64_t length) = NULL; #endif static int (*next_unlink) (const char *pathname) = NULL; +static int (*next_unlinkat) (int dirfd, const char *pathname, int flags) = NULL; +static int (*next___fxstatat64) (int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags) = NULL; #ifdef HAVE_ULCKPWDF /* static int (*next_ulckpwdf) (void) = NULL; */ #endif @@ -678,6 +680,8 @@ nextsym(truncate64, "truncate64"); #endif nextsym(unlink, "unlink"); + nextsym(unlinkat, "unlinkat"); + nextsym(__fxstatat64, "__fxstatat64"); #ifdef HAVE_ULCKPWDF /* nextsym(ulckpwdf, "ulckpwdf"); */ #endif @@ -2222,6 +2226,24 @@ return next_unlink(pathname); } +/* #include <fcntl.h> */ +int unlinkat (int dirfd, const char *pathname, int flags) +{ + char *fakechroot_path, *fakechroot_ptr, fakechroot_buf[FAKECHROOT_MAXPATH]; + expand_chroot_path(pathname, fakechroot_path, fakechroot_ptr, fakechroot_buf); + if (next_unlinkat == NULL) fakechroot_init(); + return next_unlinkat(dirfd, pathname, flags); +} + +/* #include <fcntl.h> */ +/* #include <sys/stat.h> */ +int __fxstatat64 (int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags) +{ + char *fakechroot_path, *fakechroot_ptr, fakechroot_buf[FAKECHROOT_MAXPATH]; + expand_chroot_path(pathname, fakechroot_path, fakechroot_ptr, fakechroot_buf); + if (next___fxstatat64 == NULL) fakechroot_init(); + return next___fxstatat64(ver, dirfd, pathname, buf, flags); +} /* #include <sys/types.h> */ /* #include <utime.h> */
pgpCDAiv1sSa1.pgp
Description: PGP signature