[packages/fakechroot] up to 2.20.1
atler
atler at pld-linux.org
Sun May 7 23:34:25 CEST 2023
commit f620193c4bdd0f626d07243d00df7bf1684a2d28
Author: Jan Palus <jpalus at fastmail.com>
Date: Sun May 7 23:33:40 2023 +0200
up to 2.20.1
- updated urls (lives on github now)
- statx patch from master
- debian patches gathered in https://github.com/dex4er/fakechroot/pull/104
fakechroot.spec | 36 +-
glibc-2.34.patch | 1727 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
statx.patch | 87 +++
3 files changed, 1835 insertions(+), 15 deletions(-)
---
diff --git a/fakechroot.spec b/fakechroot.spec
index 5a207c5..b47881c 100644
--- a/fakechroot.spec
+++ b/fakechroot.spec
@@ -1,17 +1,18 @@
Summary: Provides a fake chroot environment to programs
Summary(pl.UTF-8): Fałszywe środowisko chroot dla programów
Name: fakechroot
-Version: 2.3
+Version: 2.20.1
Release: 1
-License: GPL
+License: LGPL v2.1+
Group: Development/Tools
-Source0: http://ftp.debian.org/debian/pool/main/f/fakechroot/%{name}_%{version}.tar.gz
-# Source0-md5: 9df72412f6a209a63bdac02d3088d604
-URL: http://fakechroot.alioth.debian.org/
+Source0: https://github.com/dex4er/fakechroot/releases/download/%{version}/%{name}-%{version}.tar.gz
+# Source0-md5: bf67c9b3a5f282f310ba8beda2fc6057
+Patch0: statx.patch
+Patch1: glibc-2.34.patch
+BuildRequires: perl-tools-pod
+URL: https://github.com/dex4er/fakechroot
BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
-%define _libdir %{_prefix}/%{_lib}/libfakechroot
-
%description
fakechroot provides a fake chroot environment to programs. A fake
chroot allows you to run programs which require root privileges on an
@@ -32,10 +33,14 @@ pakietów bez uprawnień roota.
%prep
%setup -q
+%patch0 -p1
+%patch1 -p1
%build
%configure \
+ --disable-silent-rules \
--disable-static
+
%{__make}
%install
@@ -44,17 +49,18 @@ rm -rf $RPM_BUILD_ROOT
%{__make} install \
DESTDIR=$RPM_BUILD_ROOT
-install -d $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version}/scripts
-cp -a doc/[!M]* $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version}
-cp -a scripts/[!M]* $RPM_BUILD_ROOT%{_docdir}/%{name}-%{version}/scripts
+%{__rm} $RPM_BUILD_ROOT%{_libdir}/fakechroot/libfakechroot.la
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(644,root,root,755)
-%doc %{_docdir}/%{name}-%{version}/*
-%attr(755,root,root) %{_bindir}/*
-%dir %{_libdir}
-%attr(755,root,root) %{_libdir}/libfakechroot.so
-%{_mandir}/man1/*
+%doc NEWS.md README.md THANKS.md scripts/*{.sh,.env,fakechroot,.pl}
+%attr(755,root,root) %{_bindir}/env.fakechroot
+%attr(755,root,root) %{_bindir}/fakechroot
+%attr(755,root,root) %{_bindir}/ldd.fakechroot
+%attr(755,root,root) %{_sbindir}/chroot.fakechroot
+%dir %{_libdir}/fakechroot
+%attr(755,root,root) %{_libdir}/fakechroot/libfakechroot.so
+%{_mandir}/man1/fakechroot.1*
diff --git a/glibc-2.34.patch b/glibc-2.34.patch
new file mode 100644
index 0000000..0e7d7f0
--- /dev/null
+++ b/glibc-2.34.patch
@@ -0,0 +1,1727 @@
+From 11589e1037372c5ad719e1e46d7462fd196caa56 Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues <josch at mister-muffin.de>
+Date: Thu, 24 Jun 2021 10:38:28 +0200
+Subject: [PATCH 01/11] src/lckpwdf.c: create an empty /etc/.pwd.lock
+
+---
+ src/lckpwdf.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/src/lckpwdf.c b/src/lckpwdf.c
+index dc0e68b5..66a058de 100644
+--- a/src/lckpwdf.c
++++ b/src/lckpwdf.c
+@@ -22,12 +22,37 @@
+
+ #ifdef HAVE_LCKPWDF
+
++#include <unistd.h>
++#include <fcntl.h>
+ #include "libfakechroot.h"
++#include "open.h"
+
+
+ wrapper(lckpwdf, int, (void))
+ {
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++
++ int file;
+ debug("lckpwdf()");
++ // lckpwdf will create an empty /etc/.pwd.lock
++ // if that file doesn't exist yet, we create it here as well
++ char* pwdlockfile = "/etc/.pwd.lock";
++ expand_chroot_path(pwdlockfile);
++
++ if ((file = nextcall(open)(pwdlockfile, O_RDONLY)) == 0) {
++ // if the file already exists, don't touch it
++ close(file);
++ return 0;
++ }
++
++ if ((file = nextcall(open)(pwdlockfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
++ // we ignore any errors (maybe /etc doesn't exist or we don't have the
++ // necessary permissions)
++ return 0;
++ }
++ // the file remains empty
++ close(file);
+ return 0;
+ }
+
+
+From 3cdb9b5426ef508c9220b4b0316954e3b7dff9ac Mon Sep 17 00:00:00 2001
+From: Hajime Yoshimori <lugia.kun at gmail.com>
+Date: Fri, 1 May 2020 21:14:32 +0900
+Subject: [PATCH 02/11] check return value of dladdr
+
+https://github.com/dex4er/fakechroot/pull/70
+---
+ src/dladdr.c | 12 +++++++-----
+ test/Makefile.am | 1 +
+ test/src/Makefile.am | 1 +
+ test/src/test-dladdr.c | 14 ++++++++++++++
+ test/t/dladdr.t | 14 ++++++++++++++
+ 5 files changed, 37 insertions(+), 5 deletions(-)
+ create mode 100644 test/src/test-dladdr.c
+ create mode 100755 test/t/dladdr.t
+
+diff --git a/src/dladdr.c b/src/dladdr.c
+index fef32579..3dffdb3f 100644
+--- a/src/dladdr.c
++++ b/src/dladdr.c
+@@ -36,11 +36,13 @@ wrapper(dladdr, int, (const void * addr, Dl_info * info))
+
+ ret = nextcall(dladdr)(addr, info);
+
+- if (info->dli_fname) {
+- narrow_chroot_path(info->dli_fname);
+- }
+- if (info->dli_sname) {
+- narrow_chroot_path(info->dli_sname);
++ if (ret != 0) {
++ if (info->dli_fname) {
++ narrow_chroot_path(info->dli_fname);
++ }
++ if (info->dli_sname) {
++ narrow_chroot_path(info->dli_sname);
++ }
+ }
+
+ return ret;
+diff --git a/test/Makefile.am b/test/Makefile.am
+index aba29538..0021b0a1 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -9,6 +9,7 @@ TESTS = \
+ t/cmd-subst.t \
+ t/cp.t \
+ t/dedotdot.t \
++ t/dladdr.t \
+ t/execlp.t \
+ t/execve-elfloader.t \
+ t/execve-null-envp.t \
+diff --git a/test/src/Makefile.am b/test/src/Makefile.am
+index 7fb3075b..5f5fde8d 100644
+--- a/test/src/Makefile.am
++++ b/test/src/Makefile.am
+@@ -3,6 +3,7 @@ check_PROGRAMS = \
+ test-chroot \
+ test-clearenv \
+ test-dedotdot \
++ test-dladdr \
+ test-execlp \
+ test-execve-null-envp \
+ test-fts \
+diff --git a/test/src/test-dladdr.c b/test/src/test-dladdr.c
+new file mode 100644
+index 00000000..5ec8d248
+--- /dev/null
++++ b/test/src/test-dladdr.c
+@@ -0,0 +1,14 @@
++#define _GNU_SOURCE
++#include <dlfcn.h>
++#include <stdlib.h>
++#include <string.h>
++#include <stdio.h>
++
++int main(int argc, char** argv)
++{
++ Dl_info info;
++ memset(&info, 0xfe, sizeof(info)); /* fill with inaccessible address */
++ int ret = dladdr(NULL, &info);
++ printf("%ld\n", ret);
++ return 0;
++}
+diff --git a/test/t/dladdr.t b/test/t/dladdr.t
+new file mode 100755
+index 00000000..fc7f9397
+--- /dev/null
++++ b/test/t/dladdr.t
+@@ -0,0 +1,14 @@
++#!/bin/sh
++
++srcdir=${srcdir:-.}
++. $srcdir/common.inc.sh
++
++prepare 1
++
++PATH=$srcdir/bin:$PATH
++
++t=`$srcdir/fakechroot.sh $testtree /bin/test-dladdr`
++[ "$t" != "0" ] && not
++ok "dladdr returns" $t
++
++cleanup
+
+From 63c2cbed6dca6196940b439736ca2c069cb9358b Mon Sep 17 00:00:00 2001
+From: Ilya Lipnitskiy <ilya.lipnitskiy at gmail.com>
+Date: Mon, 22 Feb 2021 21:44:07 -0800
+Subject: [PATCH 03/11] tmpnam.c: fix heap overflow
+
+https://github.com/dex4er/fakechroot/pull/85
+
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy at gmail.com>
+---
+ src/tmpnam.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/tmpnam.c b/src/tmpnam.c
+index ce60817a..917ee6b7 100644
+--- a/src/tmpnam.c
++++ b/src/tmpnam.c
+@@ -42,7 +42,7 @@ wrapper(tmpnam, char *, (char * s))
+
+ expand_chroot_path(ptr);
+
+- ptr2 = malloc(strlen(ptr));
++ ptr2 = malloc(strlen(ptr) + 1);
+ if (ptr2 == NULL) return NULL;
+
+ strcpy(ptr2, ptr);
+
+From be3a291ef37ace606ec2845f6c1b645b981805cb Mon Sep 17 00:00:00 2001
+From: Ilya Lipnitskiy <ilya.lipnitskiy at gmail.com>
+Date: Mon, 22 Feb 2021 21:46:36 -0800
+Subject: [PATCH 04/11] declare missing bufs, remove ver from lstat
+
+https://github.com/dex4er/fakechroot/pull/85
+
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy at gmail.com>
+---
+ src/lstat.c | 8 +++++---
+ src/lstat.h | 2 +-
+ src/mknod.c | 2 ++
+ src/stat.c | 2 ++
+ src/stat64.c | 2 ++
+ 5 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/src/lstat.c b/src/lstat.c
+index 3f6d819f..54e3263f 100644
+--- a/src/lstat.c
++++ b/src/lstat.c
+@@ -28,9 +28,11 @@
+ #include "lstat.h"
+
+
+-wrapper(lstat, int, (int ver, const char * filename, struct stat * buf))
++wrapper(lstat, int, (const char * filename, struct stat * buf))
+ {
+- debug("lstat(%d, \"%s\", &buf)", ver, filename);
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("lstat(\"%s\", &buf)", filename);
+
+ if (!fakechroot_localdir(filename)) {
+ if (filename != NULL) {
+@@ -40,7 +42,7 @@ wrapper(lstat, int, (int ver, const char * filename, struct stat * buf))
+ }
+ }
+
+- return lstat_rel(ver, filename, buf);
++ return lstat_rel(filename, buf);
+ }
+
+
+diff --git a/src/lstat.h b/src/lstat.h
+index 751c1ead..ee483033 100644
+--- a/src/lstat.h
++++ b/src/lstat.h
+@@ -26,7 +26,7 @@
+
+ #ifndef HAVE___LXSTAT
+
+-wrapper_proto(lstat, int, (int, const char *, struct stat *));
++wrapper_proto(lstat, int, (const char *, struct stat *));
+
+ int lstat_rel(const char *, struct stat *);
+
+diff --git a/src/mknod.c b/src/mknod.c
+index 52fd33b2..27710372 100644
+--- a/src/mknod.c
++++ b/src/mknod.c
+@@ -28,6 +28,8 @@
+
+ wrapper(mknod, int, (const char * pathname, mode_t mode, dev_t dev))
+ {
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
+ debug("mknod(\"%s\", 0%o, %ld)", pathname, mode, dev);
+ expand_chroot_path(pathname);
+ return nextcall(mknod)(pathname, mode, dev);
+diff --git a/src/stat.c b/src/stat.c
+index 78456620..7b377933 100644
+--- a/src/stat.c
++++ b/src/stat.c
+@@ -33,6 +33,8 @@
+
+ wrapper(stat, int, (const char * file_name, struct stat * buf))
+ {
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
+ debug("stat(\"%s\", &buf)", file_name);
+ expand_chroot_path(file_name);
+ return nextcall(stat)(file_name, buf);
+diff --git a/src/stat64.c b/src/stat64.c
+index aac9c75f..a360f66f 100644
+--- a/src/stat64.c
++++ b/src/stat64.c
+@@ -34,6 +34,8 @@
+
+ wrapper(stat64, int, (const char * file_name, struct stat64 * buf))
+ {
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
+ debug("stat64(\"%s\", &buf)", file_name);
+ expand_chroot_path(file_name);
+ return nextcall(stat64)(file_name, buf);
+
+From 26f69c2c3120b9b059209c7566850ef5187de56a Mon Sep 17 00:00:00 2001
+From: Ilya Lipnitskiy <ilya.lipnitskiy at gmail.com>
+Date: Mon, 22 Feb 2021 21:47:09 -0800
+Subject: [PATCH 05/11] fix glibc 2.33+ compatibility
+
+https://github.com/dex4er/fakechroot/pull/85
+
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy at gmail.com>
+---
+ configure.ac | 20 ++++++++++++++++++++
+ src/ftw.c | 2 +-
+ src/ftw64.c | 14 +++++++++++---
+ src/libfakechroot.h | 15 +++++++++++++++
+ src/lstat.c | 2 +-
+ src/lstat.h | 2 +-
+ src/lstat64.c | 2 +-
+ src/mknod.c | 2 +-
+ src/mknodat.c | 2 +-
+ src/stat.c | 2 +-
+ src/stat64.c | 2 +-
+ 11 files changed, 54 insertions(+), 11 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index f8cdb323..9cc2e779 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -75,6 +75,26 @@ ACX_CHECK_C_ATTRIBUTE_VISIBILITY
+ # Checks for libraries.
+ AC_CHECK_LIB([dl], [dlsym])
+
++AH_TEMPLATE([NEW_GLIBC], [glibc >= 2.33])
++AC_MSG_CHECKING([for glibc 2.33+])
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
++ #include <sys/stat.h>
++ ]], [[
++#ifdef __GLIBC__
++#if !__GLIBC_PREREQ(2,33)
++#error glibc<2.33
++#endif
++#else
++#error not glibc
++#endif
++ ]])],[
++ AC_DEFINE(NEW_GLIBC,1)
++ AC_MSG_RESULT([yes])
++ ],[
++ AC_DEFINE(NEW_GLIBC,0)
++ AC_MSG_RESULT([no])
++ ])
++
+ # Checks for header files.
+ AC_HEADER_DIRENT
+ AC_HEADER_STDC
+diff --git a/src/ftw.c b/src/ftw.c
+index 92fc126c..a9abc853 100644
+--- a/src/ftw.c
++++ b/src/ftw.c
+@@ -185,7 +185,7 @@ int rpl_lstat (const char *, struct stat *);
+ # define NFTW_NEW_NAME __new_nftw
+ # define INO_T ino_t
+ # define STAT stat
+-# ifdef _LIBC
++# if defined(_LIBC) && !NEW_GLIBC
+ # define LXSTAT __lxstat
+ # define XSTAT __xstat
+ # define FXSTATAT __fxstatat
+diff --git a/src/ftw64.c b/src/ftw64.c
+index 7cc8cdfd..cee1f2bc 100644
+--- a/src/ftw64.c
++++ b/src/ftw64.c
+@@ -18,6 +18,8 @@
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
++#include "config.h"
++
+ #define __FTW64_C
+ #define FTW_NAME ftw64
+ #define NFTW_NAME nftw64
+@@ -25,9 +27,15 @@
+ #define NFTW_NEW_NAME __new_nftw64
+ #define INO_T ino64_t
+ #define STAT stat64
+-#define LXSTAT __lxstat64
+-#define XSTAT __xstat64
+-#define FXSTATAT __fxstatat64
++#if NEW_GLIBC
++# define LXSTAT(V,f,sb) lstat64 (f,sb)
++# define XSTAT(V,f,sb) stat64 (f,sb)
++# define FXSTATAT(V,d,f,sb,m) fstatat64 (d, f, sb, m)
++#else
++# define LXSTAT __lxstat64
++# define XSTAT __xstat64
++# define FXSTATAT __fxstatat64
++#endif
+ #define FTW_FUNC_T __ftw64_func_t
+ #define NFTW_FUNC_T __nftw64_func_t
+
+diff --git a/src/libfakechroot.h b/src/libfakechroot.h
+index 4cf199ff..64ff15fb 100644
+--- a/src/libfakechroot.h
++++ b/src/libfakechroot.h
+@@ -200,6 +200,21 @@
+ # endif
+ #endif
+
++#ifndef _STAT_VER
++ #if defined (__aarch64__)
++ #define _STAT_VER 0
++ #elif defined (__powerpc__) && __WORDSIZE == 64
++ #define _STAT_VER 1
++ #elif defined (__riscv) && __riscv_xlen==64
++ #define _STAT_VER 0
++ #elif defined (__s390x__)
++ #define _STAT_VER 1
++ #elif defined (__x86_64__)
++ #define _STAT_VER 1
++ #else
++ #define _STAT_VER 3
++ #endif
++#endif
+
+ typedef void (*fakechroot_wrapperfn_t)(void);
+
+diff --git a/src/lstat.c b/src/lstat.c
+index 54e3263f..fa383234 100644
+--- a/src/lstat.c
++++ b/src/lstat.c
+@@ -20,7 +20,7 @@
+
+ #include <config.h>
+
+-#ifndef HAVE___LXSTAT
++#if !defined(HAVE___LXSTAT) || NEW_GLIBC
+
+ #include <sys/stat.h>
+ #include <unistd.h>
+diff --git a/src/lstat.h b/src/lstat.h
+index ee483033..c46a2b9b 100644
+--- a/src/lstat.h
++++ b/src/lstat.h
+@@ -24,7 +24,7 @@
+ #include <config.h>
+ #include "libfakechroot.h"
+
+-#ifndef HAVE___LXSTAT
++#if !defined(HAVE___LXSTAT) || NEW_GLIBC
+
+ wrapper_proto(lstat, int, (const char *, struct stat *));
+
+diff --git a/src/lstat64.c b/src/lstat64.c
+index b6212fc8..a332d7c3 100644
+--- a/src/lstat64.c
++++ b/src/lstat64.c
+@@ -20,7 +20,7 @@
+
+ #include <config.h>
+
+-#if defined(HAVE_LSTAT64) && !defined(HAVE___LXSTAT64)
++#if defined(HAVE_LSTAT64) && (!defined(HAVE___LXSTAT64) || NEW_GLIBC)
+
+ #define _LARGEFILE64_SOURCE
+ #define _BSD_SOURCE
+diff --git a/src/mknod.c b/src/mknod.c
+index 27710372..aeb750b0 100644
+--- a/src/mknod.c
++++ b/src/mknod.c
+@@ -20,7 +20,7 @@
+
+ #include <config.h>
+
+-#ifndef HAVE___XMKNOD
++#if !defined(HAVE___XMKNOD) || NEW_GLIBC
+
+ #include <sys/stat.h>
+ #include "libfakechroot.h"
+diff --git a/src/mknodat.c b/src/mknodat.c
+index 732a22bc..3239b357 100644
+--- a/src/mknodat.c
++++ b/src/mknodat.c
+@@ -20,7 +20,7 @@
+
+ #include <config.h>
+
+-#if defined(HAVE_MKNODAT) && !defined(HAVE___XMKNODAT)
++#if defined(HAVE_MKNODAT) && (!defined(HAVE___XMKNODAT) || NEW_GLIBC)
+
+ #define _ATFILE_SOURCE
+ #include <sys/stat.h>
+diff --git a/src/stat.c b/src/stat.c
+index 7b377933..5ef57bab 100644
+--- a/src/stat.c
++++ b/src/stat.c
+@@ -20,7 +20,7 @@
+
+ #include <config.h>
+
+-#ifndef HAVE___XSTAT
++#if !defined(HAVE___XSTAT) || NEW_GLIBC
+
+ #define _BSD_SOURCE
+ #define _DEFAULT_SOURCE
+diff --git a/src/stat64.c b/src/stat64.c
+index a360f66f..993ce808 100644
+--- a/src/stat64.c
++++ b/src/stat64.c
+@@ -20,7 +20,7 @@
+
+ #include <config.h>
+
+-#if defined(HAVE_STAT64) && !defined(HAVE___XSTAT64)
++#if defined(HAVE_STAT64) && (!defined(HAVE___XSTAT64) || NEW_GLIBC)
+
+ #define _BSD_SOURCE
+ #define _LARGEFILE64_SOURCE
+
+From 5366e9a366b213b879abf0f0a3aeb3409d3b57ed Mon Sep 17 00:00:00 2001
+From: neok-m4700 <neok-m4700 at users.noreply.github.com>
+Date: Wed, 24 Feb 2021 17:36:57 +0100
+Subject: [PATCH 06/11] wrap fstatat and fstatat64
+
+https://github.com/dex4er/fakechroot/pull/86
+---
+ configure.ac | 2 ++
+ src/Makefile.am | 2 ++
+ src/fstatat.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ src/fstatat64.c | 43 +++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 89 insertions(+)
+ create mode 100644 src/fstatat.c
+ create mode 100644 src/fstatat64.c
+
+diff --git a/configure.ac b/configure.ac
+index 9cc2e779..5b3053e1 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -218,6 +218,8 @@ AC_CHECK_FUNCS(m4_normalize([
+ freopen64
+ fstat
+ fstat64
++ fstatat
++ fstatat64
+ fts_children
+ fts_open
+ fts_read
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 60663452..eb311c0a 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -61,6 +61,8 @@ libfakechroot_la_SOURCES = \
+ fopen64.c \
+ freopen.c \
+ freopen64.c \
++ fstatat.c \
++ fstatat64.c \
+ fts.c \
+ fts64.c \
+ ftw.c \
+diff --git a/src/fstatat.c b/src/fstatat.c
+new file mode 100644
+index 00000000..ca7578b3
+--- /dev/null
++++ b/src/fstatat.c
+@@ -0,0 +1,42 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2021 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE_FSTATAT
++
++#define _ATFILE_SOURCE
++#define _POSIX_C_SOURCE 200809L
++#include <sys/stat.h>
++#include <limits.h>
++#include "libfakechroot.h"
++
++wrapper(fstatat, int, (int dirfd, const char *pathname, struct stat *buf, int flags))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("fstatat(%d, \"%s\", &buf, %d)", dirfd, pathname, flags);
++ expand_chroot_path_at(dirfd, pathname);
++ return nextcall(fstatat)(dirfd, pathname, buf, flags);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+diff --git a/src/fstatat64.c b/src/fstatat64.c
+new file mode 100644
+index 00000000..18633725
+--- /dev/null
++++ b/src/fstatat64.c
+@@ -0,0 +1,43 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2021 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE_FSTATAT64
++
++#define _ATFILE_SOURCE
++#define _POSIX_C_SOURCE 200809L
++#define _LARGEFILE64_SOURCE
++#include <sys/stat.h>
++#include <limits.h>
++#include "libfakechroot.h"
++
++wrapper(fstatat64, int, (int dirfd, const char *pathname, struct stat64 *buf, int flags))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("fstatat64(%d, \"%s\", &buf, %d)", dirfd, pathname, flags);
++ expand_chroot_path_at(dirfd, pathname);
++ return nextcall(fstatat64)(dirfd, pathname, buf, flags);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+
+From bc7ef087c17a475ec03768053fa22c2193ae7fc2 Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues <josch at mister-muffin.de>
+Date: Wed, 24 Aug 2022 08:26:04 +0200
+Subject: [PATCH 07/11] Wrap all functions accessing /etc/passwd, /etc/group
+ and /etc/shadow
+
+Starting with glibc 2.32 the compat nss module for getpwnam calls
+__nss_files_fopen (which is a GLIBC_PRIVATE symbol provided by glibc)
+instead of fopen (see 299210c1fa67e2dfb564475986fce11cd33db9ad). This
+leads to getpwnam calls accessing /etc/passwd from *outside* the chroot
+and as a result programs like adduser do not work correctly anymore
+under fakechroot.
+
+Starting with glibc 2.34 the __nss_files_fopen was moved from nss to
+libc.so and thus wrapping it with LD_PRELOAD has no affect anymore
+(see 6212bb67f4695962748a5981e1b9fea105af74f6).
+
+So now we also wrap all the functions accessing /etc/passwd, /etc/group
+and /etc/shadow. This solution will ignore NIS, LDAP or other local files
+as potentially configured in /etc/nsswitch.conf.
+
+https://github.com/dex4er/fakechroot/pull/98
+---
+ src/Makefile.am | 1 +
+ src/passwd.c | 296 +++++++++++++++++++++++++++++++++++++++++
+ test/Makefile.am | 1 +
+ test/src/Makefile.am | 1 +
+ test/src/test-passwd.c | 28 ++++
+ test/t/passwd.t | 23 ++++
+ test/testtree.sh | 6 +
+ 7 files changed, 356 insertions(+)
+ create mode 100644 src/passwd.c
+ create mode 100644 test/src/test-passwd.c
+ create mode 100755 test/t/passwd.t
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index eb311c0a..6e9d9ae1 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -120,6 +120,7 @@ libfakechroot_la_SOURCES = \
+ openat64.c \
+ opendir.c \
+ opendir.h \
++ passwd.c \
+ pathconf.c \
+ popen.c \
+ posix_spawn.c \
+diff --git a/src/passwd.c b/src/passwd.c
+new file mode 100644
+index 00000000..d4cee86c
+--- /dev/null
++++ b/src/passwd.c
+@@ -0,0 +1,296 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2013 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++/*
++ * Starting with glibc 2.32 the compat nss module for getpwnam calls
++ * __nss_files_fopen (which is a GLIBC_PRIVATE symbol provided by glibc)
++ * instead of fopen (see 299210c1fa67e2dfb564475986fce11cd33db9ad). This
++ * leads to getpwnam calls accessing /etc/passwd from *outside* the chroot
++ * and as a result programs like adduser do not work correctly anymore
++ * under fakechroot.
++ *
++ * Starting with glibc 2.34 the __nss_files_fopen was moved from nss to
++ * libc.so and thus wrapping it with LD_PRELOAD has no affect anymore
++ * (see 6212bb67f4695962748a5981e1b9fea105af74f6).
++ *
++ * So now we also wrap all the functions accessing /etc/passwd, /etc/group
++ * and /etc/shadow. This solution will ignore NIS, LDAP or other local files
++ * as potentially configured in /etc/nsswitch.conf.
++ */
++
++#include <gnu/libc-version.h>
++#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 32)
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <sys/types.h>
++#include <pwd.h>
++#include <grp.h>
++#include <shadow.h>
++#include "libfakechroot.h"
++
++/* getpwent, setpwent, endpwent, getpwuid, getpwnam */
++
++static FILE *pw_f;
++
++wrapper(getpwent, struct passwd *, (void))
++{
++ if (!pw_f) pw_f = fopen("/etc/passwd", "rbe");
++ if (!pw_f) return 0;
++ return fgetpwent(pw_f);
++}
++
++wrapper (getpwent_r, int, (struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp))
++{
++ if (!pw_f) pw_f = fopen("/etc/passwd", "rbe");
++ if (!pw_f) return 0;
++ return fgetpwent_r(pw_f, pwbuf, buf, buflen, pwbufp);
++}
++
++wrapper(setpwent, void, (void))
++{
++ if (pw_f) fclose(pw_f);
++ pw_f = 0;
++}
++
++wrapper(endpwent, void, (void))
++{
++ if (pw_f) fclose(pw_f);
++ pw_f = 0;
++}
++
++wrapper(getpwuid, struct passwd *, (uid_t uid))
++{
++ debug("getpwuid(\"%ul\")", uid);
++ FILE *f = fopen("/etc/passwd", "rbe");
++ if (!f) {
++ return NULL;
++ }
++ struct passwd *res = NULL;
++ while ((res = fgetpwent(f))) {
++ if (res->pw_uid == uid)
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++wrapper(getpwuid_r, int, (uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result))
++{
++ debug("getpwuid_r(\"%ul\")", uid);
++ FILE *f = fopen("/etc/passwd", "rbe");
++ if (!f) {
++ return errno;
++ }
++ int res;
++ while (!(res = fgetpwent_r(f, pwd, buf, buflen, result))) {
++ if (pwd->pw_uid == uid)
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++wrapper(getpwnam, struct passwd *, (const char *name))
++{
++ debug("getpwnam(\"%s\")", name);
++ FILE *f = fopen("/etc/passwd", "rbe");
++ if (!f) {
++ return NULL;
++ }
++ struct passwd *res = NULL;
++ while ((res = fgetpwent(f))) {
++ if (name && !strcmp(name, res->pw_name))
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++wrapper(getpwnam_r, int, (const char *name, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result))
++{
++ debug("getpwnam_r(\"%s\")", name);
++ FILE *f = fopen("/etc/passwd", "rbe");
++ if (!f) {
++ return errno;
++ }
++ int res;
++ while (!(res = fgetpwent_r(f, pwd, buf, buflen, result))) {
++ if (name && !strcmp(name, pwd->pw_name))
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++/* getgrent, setgrent, endgrent, getgrgid, getgrnam */
++
++static FILE *gr_f;
++
++wrapper(getgrent, struct group *, (void))
++{
++ if (!gr_f) gr_f = fopen("/etc/group", "rbe");
++ if (!gr_f) return 0;
++ return fgetgrent(gr_f);
++}
++
++wrapper (getgrent_r, int, (struct group *gbuf, char *buf, size_t buflen, struct group **gbufp))
++{
++ if (!gr_f) gr_f = fopen("/etc/group", "rbe");
++ if (!gr_f) return 0;
++ return fgetgrent_r(gr_f, gbuf, buf, buflen, gbufp);
++}
++
++wrapper(setgrent, void, (void))
++{
++ if (gr_f) fclose(gr_f);
++ gr_f = 0;
++}
++
++wrapper(endgrent, void, (void))
++{
++ if (gr_f) fclose(gr_f);
++ gr_f = 0;
++}
++
++wrapper(getgrgid, struct group *, (gid_t gid))
++{
++ debug("getgrgid(\"%ul\")", gid);
++ FILE *f = fopen("/etc/group", "rbe");
++ if (!f) {
++ return NULL;
++ }
++ struct group *res = NULL;
++ while ((res = fgetgrent(f))) {
++ if (res->gr_gid == gid)
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++wrapper(getgrgid_r, int, (gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result))
++{
++ debug("getgrgid_r(\"%ul\")", gid);
++ FILE *f = fopen("/etc/group", "rbe");
++ if (!f) {
++ return errno;
++ }
++ int res;
++ while (!(res = fgetgrent_r(f, grp, buf, buflen, result))) {
++ if (grp->gr_gid == gid)
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++wrapper(getgrnam, struct group *, (const char *name))
++{
++ debug("getgrnam(\"%s\")", name);
++ FILE *f = fopen("/etc/group", "rbe");
++ if (!f) {
++ return NULL;
++ }
++ struct group *res = NULL;
++ while ((res = fgetgrent(f))) {
++ if (name && !strcmp(name, res->gr_name))
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++wrapper(getgrnam_r, int, (const char *name, struct group *grp, char *buf, size_t buflen, struct group **result))
++{
++ debug("getgrnam_r(\"%s\")", name);
++ FILE *f = fopen("/etc/group", "rbe");
++ if (!f) {
++ return errno;
++ }
++ int res;
++ while (!(res = fgetgrent_r(f, grp, buf, buflen, result))) {
++ if (name && !strcmp(name, grp->gr_name))
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++/* getspent, setspent, endspent, getspnam */
++
++static FILE *sp_f;
++
++wrapper(getspent, struct spwd *, (void))
++{
++ if (!sp_f) sp_f = fopen("/etc/shadow", "rbe");
++ if (!sp_f) return 0;
++ return fgetspent(sp_f);
++}
++
++wrapper(setspent, void, (void))
++{
++ if (sp_f) fclose(sp_f);
++ sp_f = 0;
++}
++
++wrapper(endspent, void, (void))
++{
++ if (sp_f) fclose(sp_f);
++ sp_f = 0;
++}
++
++wrapper(getspnam, struct spwd *, (const char *name))
++{
++ debug("getspnam(\"%s\")", name);
++ FILE *f = fopen("/etc/shadow", "rbe");
++ if (!f) {
++ return NULL;
++ }
++ struct spwd *res = NULL;
++ while ((res = fgetspent(f))) {
++ if (name && !strcmp(name, res->sp_namp))
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++wrapper(getspnam_r, int, (const char *name, struct spwd *spbuf, char *buf, size_t buflen, struct spwd **spbufp))
++{
++ debug("getspnam_r(\"%s\")", name);
++ FILE *f = fopen("/etc/shadow", "rbe");
++ if (!f) {
++ return errno;
++ }
++ int res;
++ while (!(res = fgetspent_r(f, spbuf, buf, buflen, spbufp))) {
++ if (name && !strcmp(name, spbuf->sp_namp))
++ break;
++ }
++ fclose(f);
++ return res;
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 0021b0a1..a1ec743d 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -22,6 +22,7 @@ TESTS = \
+ t/mkstemps.t \
+ t/mktemp.t \
+ t/opendir.t \
++ t/passwd.t \
+ t/popen.t \
+ t/posix_spawn.t \
+ t/posix_spawnp.t \
+diff --git a/test/src/Makefile.am b/test/src/Makefile.am
+index 5f5fde8d..594a8e0f 100644
+--- a/test/src/Makefile.am
++++ b/test/src/Makefile.am
+@@ -15,6 +15,7 @@ check_PROGRAMS = \
+ test-mkstemps \
+ test-mktemp \
+ test-opendir \
++ test-passwd \
+ test-popen \
+ test-posix_spawn \
+ test-posix_spawnp \
+diff --git a/test/src/test-passwd.c b/test/src/test-passwd.c
+new file mode 100644
+index 00000000..fb9c8c4c
+--- /dev/null
++++ b/test/src/test-passwd.c
+@@ -0,0 +1,28 @@
++#include <stdlib.h>
++#include <stdio.h>
++#include <pwd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <unistd.h>
++
++int main (int argc, char *argv[]) {
++ struct passwd *pwd;
++
++ if (argc != 2) {
++ fprintf(stderr, "Usage: %s username\n", argv[0]);
++ exit(EXIT_FAILURE);
++ }
++
++ pwd = getpwnam(argv[1]);
++ if (pwd == NULL) {
++ if (errno == 0) {
++ printf("Not found\n");
++ } else {
++ perror("getpwnam");
++ }
++ exit(EXIT_FAILURE);
++ }
++
++ printf("%jd\n", (intmax_t)(pwd->pw_uid));
++ exit(EXIT_SUCCESS);
++}
+diff --git a/test/t/passwd.t b/test/t/passwd.t
+new file mode 100755
+index 00000000..5c3414e0
+--- /dev/null
++++ b/test/t/passwd.t
+@@ -0,0 +1,23 @@
++#!/bin/sh
++
++srcdir=${srcdir:-.}
++. $srcdir/common.inc.sh
++
++prepare 4
++
++for chroot in chroot fakechroot; do
++ if [ $chroot = "chroot" ] && ! is_root; then
++ skip $(( $tap_plan / 2 )) "not root"
++ else
++
++ t=`$srcdir/$chroot.sh $testtree /bin/test-passwd user 2>&1`
++ test "$t" = "1337" || not
++ ok "$chroot uid is" $t
++
++ t=`$srcdir/$chroot.sh $testtree getent group user 2>&1`
++ test "$t" = "user:x:1337:" || not
++ ok "$chroot getent group user is" $t
++ fi
++done
++
++cleanup
+diff --git a/test/testtree.sh b/test/testtree.sh
+index ee35fc26..d857a195 100755
+--- a/test/testtree.sh
++++ b/test/testtree.sh
+@@ -32,6 +32,10 @@ do
+ mkdir -p $destdir/$d
+ done
+
++echo "user:x:1337:1337:user:/home/user:/bin/bash" > $destdir/etc/passwd
++echo "root:x:0:" > $destdir/etc/group
++echo "user:x:1337:" >> $destdir/etc/group
++
+ for d in \
+ /dev \
+ /proc
+@@ -64,6 +68,7 @@ for p in \
+ '/usr/bin/dirname' \
+ '/usr/bin/env' \
+ '/usr/bin/find' \
++ '/usr/bin/getent' \
+ '/usr/bin/id' \
+ '/usr/bin/ischroot' \
+ '/usr/bin/less' \
+@@ -116,6 +121,7 @@ for p in \
+ 'libm.so.*' \
+ 'libncurses.so.*' \
+ 'libncursesw.so.*' \
++ 'libnss_*.so.*' \
+ 'libpcre*.so.*' \
+ 'libpthread.so.*' \
+ 'libreadline.so.*' \
+
+From d9a47178203931231987d10117acb5684d12ed4c Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues <josch at mister-muffin.de>
+Date: Tue, 1 Nov 2022 00:47:56 +0100
+Subject: [PATCH 08/11] add test/t/rm.t and amend test/t/touch.t with
+ --no-dereference test
+
+ - test/t/rm.t will fail under glibc 2.34 unless __stat64_time64 functions are
+ wrapped
+ - test/t/touch.t will fail under glibc 2.34 unless __lstat64_time64 is
+ wrapped
+---
+ test/Makefile.am | 1 +
+ test/t/rm.t | 25 +++++++++++++++++++++++++
+ test/t/touch.t | 17 +++++++++++++++--
+ 3 files changed, 41 insertions(+), 2 deletions(-)
+ create mode 100755 test/t/rm.t
+
+diff --git a/test/Makefile.am b/test/Makefile.am
+index a1ec743d..88e740e5 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -29,6 +29,7 @@ TESTS = \
+ t/pwd.t \
+ t/readlink.t \
+ t/realpath.t \
++ t/rm.t \
+ t/socket-af_unix.t \
+ t/statfs.t \
+ t/statvfs.t \
+diff --git a/test/t/rm.t b/test/t/rm.t
+new file mode 100755
+index 00000000..9ecf88c9
+--- /dev/null
++++ b/test/t/rm.t
+@@ -0,0 +1,25 @@
++#!/bin/sh
++
++srcdir=${srcdir:-.}
++. $srcdir/common.inc.sh
++
++prepare 2
++
++for chroot in chroot fakechroot; do
++
++ if [ $chroot = "chroot" ] && ! is_root; then
++ skip $(( $tap_plan / 2 )) "not root"
++ else
++
++ mkdir -p $testtree/dir-$chroot
++ echo 'something' > $testtree/dir-$chroot/file
++
++ $srcdir/$chroot.sh $testtree /bin/sh -c "rm -r /dir-$chroot"
++ test -e $testtree/dir-$chroot && not
++ ok "$chroot rm -r /dir-$chroot:" $t
++
++ fi
++
++done
++
++cleanup
+diff --git a/test/t/touch.t b/test/t/touch.t
+index fbea316b..cc05a2ba 100755
+--- a/test/t/touch.t
++++ b/test/t/touch.t
+@@ -3,12 +3,12 @@
+ srcdir=${srcdir:-.}
+ . $srcdir/common.inc.sh
+
+-prepare 16
++prepare 24
+
+ . $srcdir/touch.inc.sh
+
+ if [ -z "$touch" ]; then
+- skip 16 "touch not found"
++ skip 24 "touch not found"
+ else
+
+ for chroot in chroot fakechroot; do
+@@ -37,6 +37,19 @@ else
+
+ sleep 1
+
++ # with --no-dereference, on 32bit, touch will use __lstat64_time64
++ t=`$srcdir/$chroot.sh $testtree $touch -h -r /tmp/$chroot-touch.txt /tmp/$chroot-touch2.txt 2>&1`
++ test "$t" = "" || not
++ ok "$chroot touch -r" $t
++ test -f $testtree/tmp/$chroot-touch2.txt || not
++ ok "$chroot $chroot-touch2.txt exists"
++ test $testtree/tmp/$chroot-touch2.txt -nt $testtree/tmp/$chroot-touch.txt && not
++ ok "$chroot $chroot-touch2.txt is not newer than touch.txt"
++ test $testtree/tmp/$chroot-touch2.txt -ot $testtree/tmp/$chroot-touch.txt && not
++ ok "$chroot $chroot-touch2.txt is not older than $chroot-touch.txt"
++
++ sleep 1
++
+ t=`$srcdir/$chroot.sh $testtree $touch -m /tmp/$chroot-touch.txt 2>&1`
+ test "$t" = "" || not
+ ok "$chroot touch -m" $t
+
+From dac74cd68cfb6eeaae9cd13bdc48737a44980df9 Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues <josch at mister-muffin.de>
+Date: Tue, 1 Nov 2022 00:48:23 +0100
+Subject: [PATCH 09/11] support glibc 2.34 by wrapping
+ __{f,l,}stat{at,}64_time64 and__utime{nsat,s,}64
+
+These functions are only wrapped on 32 bit platforms like i386, armel or
+armhf. On 64 bit platforms, the corresponding HAVE_* macros will not be
+defined.
+
+ * __fstatat64_time64
+ * __lstat64_time64
+ * __stat64_time64
+ * __utime64
+ * __utimensat64
+ * __utimes64
+---
+ configure.ac | 6 +++++
+ src/Makefile.am | 6 +++++
+ src/__fstatat64_time64.c | 44 ++++++++++++++++++++++++++++++++++++
+ src/__lstat64_time64.c | 49 ++++++++++++++++++++++++++++++++++++++++
+ src/__stat64_time64.c | 47 ++++++++++++++++++++++++++++++++++++++
+ src/__utime64.c | 41 +++++++++++++++++++++++++++++++++
+ src/__utimensat64.c | 42 ++++++++++++++++++++++++++++++++++
+ src/__utimes64.c | 42 ++++++++++++++++++++++++++++++++++
+ 8 files changed, 277 insertions(+)
+ create mode 100644 src/__fstatat64_time64.c
+ create mode 100644 src/__lstat64_time64.c
+ create mode 100644 src/__stat64_time64.c
+ create mode 100644 src/__utime64.c
+ create mode 100644 src/__utimensat64.c
+ create mode 100644 src/__utimes64.c
+
+diff --git a/configure.ac b/configure.ac
+index 5b3053e1..26c06116 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -158,11 +158,13 @@ ACX_CHECK_FTS_NAME_TYPE
+ # Checks for library functions.
+ AC_CHECK_FUNCS(m4_normalize([
+ __chk_fail
++ __fstatat64_time64
+ __fxstat64
+ __fxstatat
+ __fxstatat64
+ __getcwd_chk
+ __getwd_chk
++ __lstat64_time64
+ __lxstat
+ __lxstat64
+ __open
+@@ -175,7 +177,11 @@ AC_CHECK_FUNCS(m4_normalize([
+ __realpath_chk
+ __readlink_chk
+ __readlinkat_chk
++ __stat64_time64
+ __statfs
++ __utime64
++ __utimensat64
++ __utimes64
+ __xmknod
+ __xmknodat
+ __xstat
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 6e9d9ae1..55193a96 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -1,9 +1,11 @@
+ pkglib_LTLIBRARIES = libfakechroot.la
+ libfakechroot_la_SOURCES = \
++ __fstatat64_time64.c \
+ __fxstatat.c \
+ __fxstatat64.c \
+ __getcwd_chk.c \
+ __getwd_chk.c \
++ __lstat64_time64.c \
+ __lxstat.c \
+ __lxstat64.c \
+ __lxstat64.h \
+@@ -18,7 +20,11 @@ libfakechroot_la_SOURCES = \
+ __readlinkat_chk.c \
+ __realpath_chk.c \
+ __realpath_chk.h \
++ __stat64_time64.c \
+ __statfs.c \
++ __utime64.c \
++ __utimensat64.c \
++ __utimes64.c \
+ __xmknod.c \
+ __xmknodat.c \
+ __xstat.c \
+diff --git a/src/__fstatat64_time64.c b/src/__fstatat64_time64.c
+new file mode 100644
+index 00000000..47a401f2
+--- /dev/null
++++ b/src/__fstatat64_time64.c
+@@ -0,0 +1,44 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2021 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE___FSTATAT64_TIME64
++
++#define _ATFILE_SOURCE
++#define _POSIX_C_SOURCE 200809L
++#include <sys/stat.h>
++#include <limits.h>
++#include "libfakechroot.h"
++
++struct __stat64_t64;
++
++wrapper(__fstatat64_time64, int, (int dirfd, const char *pathname, struct __stat64_t64 *buf, int flags))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("__fstatat64_time64(%d, \"%s\", &buf, %d)", dirfd, pathname, flags);
++ expand_chroot_path_at(dirfd, pathname);
++ return nextcall(__fstatat64_time64)(dirfd, pathname, buf, flags);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+diff --git a/src/__lstat64_time64.c b/src/__lstat64_time64.c
+new file mode 100644
+index 00000000..e3e84002
+--- /dev/null
++++ b/src/__lstat64_time64.c
+@@ -0,0 +1,49 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2021 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE___LSTAT64_TIME64
++
++#define _ATFILE_SOURCE
++#define _POSIX_C_SOURCE 200809L
++#include <sys/stat.h>
++#include <limits.h>
++#include "libfakechroot.h"
++
++struct __stat64_t64;
++
++wrapper(__lstat64_time64, int, (const char *filename, struct __stat64_t64 *buf))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ char resolved[FAKECHROOT_PATH_MAX];
++ debug("__lstat64_time64(\"%s\", &buf)", filename);
++ if (rel2abs(filename, resolved) == NULL) {
++ return -1;
++ }
++ filename = resolved;
++ expand_chroot_path(filename);
++ return nextcall(__lstat64_time64)(filename, buf);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+diff --git a/src/__stat64_time64.c b/src/__stat64_time64.c
+new file mode 100644
+index 00000000..1b65345e
+--- /dev/null
++++ b/src/__stat64_time64.c
+@@ -0,0 +1,47 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010-2015 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE___STAT64_TIME64
++
++#define _BSD_SOURCE
++#define _LARGEFILE64_SOURCE
++#define _DEFAULT_SOURCE
++#include <sys/stat.h>
++#include <limits.h>
++#include <stdlib.h>
++
++#include "libfakechroot.h"
++
++struct __stat64_t64;
++
++wrapper(__stat64_time64, int, (const char * file_name, struct __stat64_t64 * buf))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("__stat64_time64(\"%s\", &buf)", file_name);
++ expand_chroot_path(file_name);
++ return nextcall(__stat64_time64)(file_name, buf);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+diff --git a/src/__utime64.c b/src/__utime64.c
+new file mode 100644
+index 00000000..65d6e831
+--- /dev/null
++++ b/src/__utime64.c
+@@ -0,0 +1,41 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2013 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE___UTIME64
++
++#define _ATFILE_SOURCE
++#define _POSIX_C_SOURCE 200809L
++#include <utime.h>
++#include "libfakechroot.h"
++
++wrapper(__utime64, int, (const char * filename, const struct utimbuf * buf))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("__utime64(\"%s\", &buf)", filename);
++ expand_chroot_path(filename);
++ return nextcall(__utime64)(filename, buf);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+diff --git a/src/__utimensat64.c b/src/__utimensat64.c
+new file mode 100644
+index 00000000..3973d64c
+--- /dev/null
++++ b/src/__utimensat64.c
+@@ -0,0 +1,42 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2013 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE___UTIMENSAT64
++
++#define _ATFILE_SOURCE
++#define _POSIX_C_SOURCE 200809L
++#include <sys/time.h>
++#include "libfakechroot.h"
++
++
++wrapper(__utimensat64, int, (int dirfd, const char * pathname, const struct timespec times [2], int flags))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("utimeat(%d, \"%s\", &buf, %d)", dirfd, pathname, flags);
++ expand_chroot_path_at(dirfd, pathname);
++ return nextcall(__utimensat64)(dirfd, pathname, times, flags);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+diff --git a/src/__utimes64.c b/src/__utimes64.c
+new file mode 100644
+index 00000000..03e57d16
+--- /dev/null
++++ b/src/__utimes64.c
+@@ -0,0 +1,42 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010, 2013 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE___UTIMES64
++
++#define _ATFILE_SOURCE
++#define _POSIX_C_SOURCE 200809L
++
++#include <sys/time.h>
++#include "libfakechroot.h"
++
++wrapper(__utimes64, int, (const char * filename, UTIMES_TYPE_ARG2(tv)))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("__utimes64(\"%s\", &tv)", filename);
++ expand_chroot_path(filename);
++ return nextcall(__utimes64)(filename, tv);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
+
+From 117d2e6e741bc4ff47e41e6879ca9e9821755ffd Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues <josch at mister-muffin.de>
+Date: Tue, 31 Jan 2023 11:43:33 +0100
+Subject: [PATCH 10/11] also investigate .interp section for architectures that
+ do not list the linker in `objdump -p` like mips64el, ppc64el and s390x
+
+---
+ scripts/ldd.fakechroot.pl | 33 +++++++++++++++++++++++++++++++++
+ test/Makefile.am | 1 +
+ test/t/ldd_interp.t | 26 ++++++++++++++++++++++++++
+ 3 files changed, 60 insertions(+)
+ create mode 100755 test/t/ldd_interp.t
+
+diff --git a/scripts/ldd.fakechroot.pl b/scripts/ldd.fakechroot.pl
+index b4bb2a8c..13a94540 100755
+--- a/scripts/ldd.fakechroot.pl
++++ b/scripts/ldd.fakechroot.pl
+@@ -124,6 +124,38 @@ sub objdump {
+ }
+ }
+
++# mips64el, ppc64el and s390x do not list the linker itself
++# if it's missing, obtain it from the .interp section
++#
++# mips64el: /lib64/ld.so.1
++# ppc64el: /lib64/ld64.so.2
++# s390x: /lib/ld64.so.1
++sub elfinterp {
++ my $file = shift;
++ my $res = '';
++ local *PIPE;
++ open PIPE, "objdump -sj .interp '$file' 2>/dev/null |";
++ while (my $line = <PIPE>) {
++ if ( $line !~ /^ [a-f0-9]+ ([a-f0-9][a-f0-9][a-f0-9 ]{6} [a-f0-9 ]{8} [a-f0-9 ]{8} [a-f0-9 ]{8}) /) {
++ next;
++ }
++ $line = $1;
++ $line =~ s/ //g;
++ $line =~ s/(..)/chr(hex($1))/eg;
++ $res .= $line;
++ }
++ close PIPE;
++
++ # remove trailing NUL byte
++ $res =~ s/\000$//;
++
++ # only add if it is missing
++ if ( $res && !exists $Libs{$res} ) {
++ push @Libs, $res;
++ $Libs{$res} = '';
++ }
++}
++
+
+ sub load_ldsoconf {
+ my ($file) = @_;
+@@ -191,6 +223,7 @@ sub load_ldsoconf {
+ }
+
+ objdump($file);
++ elfinterp($file_in_chroot);
+
+ if ($Dynamic == 0) {
+ print "\tnot a dynamic executable\n";
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 88e740e5..d7f98f03 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -19,6 +19,7 @@ TESTS = \
+ t/host.t \
+ t/java.t \
+ t/jemalloc.t \
++ t/ldd_interp.t \
+ t/mkstemps.t \
+ t/mktemp.t \
+ t/opendir.t \
+diff --git a/test/t/ldd_interp.t b/test/t/ldd_interp.t
+new file mode 100755
+index 00000000..7c968bb8
+--- /dev/null
++++ b/test/t/ldd_interp.t
+@@ -0,0 +1,26 @@
++#!/bin/sh
++
++srcdir=${srcdir:-.}
++. $srcdir/common.inc.sh
++
++plan 1
++
++pwd=`dirname $0`
++abs_top_srcdir=${abs_top_srcdir:-`cd "$pwd/../.." 2>/dev/null && pwd -P`}
++
++interp_file=$(file /bin/true | sed 's/^.*, interpreter \([^,]\+\), .*$/\1/')
++interp_readelf=$(readelf --string-dump=.interp /bin/true | sed -ne 's/^ \[ \+[0-9]\+\] //p')
++
++# diag "$interp_file" "$interp_readelf"
++
++test "$interp_file" = "$interp_readelf" || not
++
++# ldd /bin/true | diag
++
++ldd /bin/true | grep --quiet "^[[:space:]]$interp_file (" || not
++
++# "$abs_top_srcdir/scripts/ldd.fakechroot" /bin/true | diag
++
++"$abs_top_srcdir/scripts/ldd.fakechroot" /bin/true | grep --quiet "^[[:space:]]$interp_file (" || not
++
++ok "ldd lists interpreter $interp_file"
+
+From 1617833d4bfa415cbe2fc1e961cb751e47697c24 Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues <josch at mister-muffin.de>
+Date: Mon, 6 Feb 2023 10:42:40 +0100
+Subject: [PATCH 11/11] test/touch.inc.sh: use testtree variable
+
+ - the variable is set in test/common.inc.sh and includes `basename $0 .t`
+ - otherwise test/t/touch.t will always get skipped
+---
+ test/touch.inc.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/test/touch.inc.sh b/test/touch.inc.sh
+index 25e0dc01..76c21321 100644
+--- a/test/touch.inc.sh
++++ b/test/touch.inc.sh
+@@ -1,6 +1,6 @@
+-if [ -x testtree/usr/bin/touch ]; then
++if [ -x $testtree/usr/bin/touch ]; then
+ touch=/usr/bin/touch
+-elif [ -x testtree/bin/touch ]; then
++elif [ -x $testtree/bin/touch ]; then
+ touch=/bin/touch
+ else
+ touch=
diff --git a/statx.patch b/statx.patch
new file mode 100644
index 0000000..d634ba4
--- /dev/null
+++ b/statx.patch
@@ -0,0 +1,87 @@
+From b42d1fb9538f680af2f31e864c555414ccba842a Mon Sep 17 00:00:00 2001
+From: Piotr Roszatycki <piotr.roszatycki at gmail.com>
+Date: Mon, 10 Feb 2020 13:59:10 -0800
+Subject: [PATCH] New `statx` function
+
+---
+ NEWS.md | 1 +
+ configure.ac | 1 +
+ src/Makefile.am | 1 +
+ src/statx.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 47 insertions(+)
+ create mode 100644 src/statx.c
+
+diff --git a/configure.ac b/configure.ac
+index a654edda..f8cdb323 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -277,6 +277,7 @@ AC_CHECK_FUNCS(m4_normalize([
+ statfs64
+ statvfs
+ statvfs64
++ statx
+ stpcpy
+ strchrnul
+ strlcpy
+diff --git a/src/Makefile.am b/src/Makefile.am
+index d729b0e1..60663452 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -152,6 +152,7 @@ libfakechroot_la_SOURCES = \
+ statfs64.c \
+ statvfs.c \
+ statvfs64.c \
++ statx.c \
+ stpcpy.c \
+ strchrnul.c \
+ strchrnul.h \
+diff --git a/src/statx.c b/src/statx.c
+new file mode 100644
+index 00000000..524f73e2
+--- /dev/null
++++ b/src/statx.c
+@@ -0,0 +1,44 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010-2020 Piotr Roszatycki <dexter at debian.org>
++
++ This library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ This library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with this library; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <config.h>
++
++#ifdef HAVE_STATX
++
++#define _GNU_SOURCE
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++
++#include "libfakechroot.h"
++
++
++wrapper(statx, int, (int dirfd, const char * pathname, int flags, unsigned int mask, struct statx * statxbuf))
++{
++ char fakechroot_abspath[FAKECHROOT_PATH_MAX];
++ char fakechroot_buf[FAKECHROOT_PATH_MAX];
++ debug("statx(%d, \"%s\", %d, %u, &statxbuf)", dirfd, pathname, flags, mask);
++ expand_chroot_path_at(dirfd, pathname);
++ return nextcall(statx)(dirfd, pathname, flags, mask, statxbuf);
++}
++
++#else
++typedef int empty_translation_unit;
++#endif
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/fakechroot.git/commitdiff/f620193c4bdd0f626d07243d00df7bf1684a2d28
More information about the pld-cvs-commit
mailing list