summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author Matteo Bernardini2024-05-19 16:34:29 +0200
committer Matteo Bernardini2024-06-08 15:01:33 +0200
commit0e0ff13414d0bed5f514834aad53e6957689885a (patch)
treeb2503bb2f286a91f937723e6323a599f4f5120bf
parentbc9d18b502448dd277146e40e6546eac0cd8d670 (diff)
downloadslackbuilds-fakechroot.tar.gz
system/fakechroot: Fix build with patches from fedora (thanks!).fakechroot
Signed-off-by: Matteo Bernardini <ponce@slackbuilds.org>
-rw-r--r--system/fakechroot/fakechroot-2.20.1-glibc-2.33.patch469
-rw-r--r--system/fakechroot/fakechroot.SlackBuild6
-rw-r--r--system/fakechroot/patches/104.patch1727
-rw-r--r--system/fakechroot/patches/80.patch22
-rw-r--r--system/fakechroot/patches/autoupdate.patch40
-rw-r--r--system/fakechroot/patches/b42d1fb9538f680af2f31e864c555414ccba842a.patch102
-rw-r--r--system/fakechroot/patches/disable_cp.t.patch11
-rw-r--r--system/fakechroot/patches/fix_test_on_32bits.patch38
8 files changed, 1944 insertions, 471 deletions
diff --git a/system/fakechroot/fakechroot-2.20.1-glibc-2.33.patch b/system/fakechroot/fakechroot-2.20.1-glibc-2.33.patch
deleted file mode 100644
index 31c2dd7843..0000000000
--- a/system/fakechroot/fakechroot-2.20.1-glibc-2.33.patch
+++ /dev/null
@@ -1,469 +0,0 @@
-From 534e6d555736b97211523970d378dfb0db2608e9 Mon Sep 17 00:00:00 2001
-From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Date: Mon, 22 Feb 2021 21:44:07 -0800
-Subject: [PATCH 1/6] tmpnam.c: fix heap overflow
-
-Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
----
- src/tmpnam.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/tmpnam.c b/src/tmpnam.c
-index ce60817..917ee6b 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 75d7e6fa191c11a791faff06a0de86eaa7801d05 Mon Sep 17 00:00:00 2001
-From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Date: Mon, 22 Feb 2021 21:46:36 -0800
-Subject: [PATCH 2/6] declare missing bufs, remove ver from lstat
-
-Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@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 3f6d819..54e3263 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 751c1ea..ee48303 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 52fd33b..2771037 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 7845662..7b37793 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 aac9c75..a360f66 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 693a3597ea7fccfb62f357503ff177bd3e3d5a89 Mon Sep 17 00:00:00 2001
-From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Date: Mon, 22 Feb 2021 21:47:09 -0800
-Subject: [PATCH 3/6] fix glibc 2.33+ compatibility
-
-Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@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 f8cdb32..9cc2e77 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 92fc126..a9abc85 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 7cc8cdf..cee1f2b 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 4cf199f..64ff15f 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 54e3263..fa38323 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 ee48303..c46a2b9 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 b6212fc..a332d7c 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 2771037..aeb750b 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 732a22b..3239b35 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 7b37793..5ef57ba 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 a360f66..993ce80 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 e7c1f3a446e594a4d0cce5f5d499c9439ce1d5c5 Mon Sep 17 00:00:00 2001
-From: neok-m4700 <neok-m4700@users.noreply.github.com>
-Date: Wed, 24 Feb 2021 17:36:57 +0100
-Subject: [PATCH 6/6] wrap fstatat and fstatat64
-
----
- 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 9cc2e77..5b3053e 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 6066345..eb311c0 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 0000000..ca7578b
---- /dev/null
-+++ b/src/fstatat.c
-@@ -0,0 +1,42 @@
-+/*
-+ libfakechroot -- fake chroot environment
-+ Copyright (c) 2010, 2021 Piotr Roszatycki <dexter@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 0000000..1863372
---- /dev/null
-+++ b/src/fstatat64.c
-@@ -0,0 +1,43 @@
-+/*
-+ libfakechroot -- fake chroot environment
-+ Copyright (c) 2010, 2021 Piotr Roszatycki <dexter@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
diff --git a/system/fakechroot/fakechroot.SlackBuild b/system/fakechroot/fakechroot.SlackBuild
index ae5854880a..db97a1ba6c 100644
--- a/system/fakechroot/fakechroot.SlackBuild
+++ b/system/fakechroot/fakechroot.SlackBuild
@@ -72,8 +72,6 @@ cd $TMP
rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
-# thanks gentoo maintainers
-patch -p1 < $CWD/fakechroot-2.20.1-glibc-2.33.patch
chown -R root:root .
find -L . \
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
@@ -81,6 +79,10 @@ find -L . \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+# get patches from fedora (thanks!)
+for i in $CWD/patches/* ; do patch -p1 < $i ; done
+autoreconf -vif
+
CFLAGS="$SLKCFLAGS" \
CXXFLAGS="$SLKCFLAGS" \
./configure \
diff --git a/system/fakechroot/patches/104.patch b/system/fakechroot/patches/104.patch
new file mode 100644
index 0000000000..0e7d7f0b52
--- /dev/null
+++ b/system/fakechroot/patches/104.patch
@@ -0,0 +1,1727 @@
+From 11589e1037372c5ad719e1e46d7462fd196caa56 Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues <josch@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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/system/fakechroot/patches/80.patch b/system/fakechroot/patches/80.patch
new file mode 100644
index 0000000000..86e586017d
--- /dev/null
+++ b/system/fakechroot/patches/80.patch
@@ -0,0 +1,22 @@
+From e291eb96db42f20a55f917aae660d416d624acaa Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= <gael.portay@collabora.com>
+Date: Fri, 4 Dec 2020 09:30:42 -0500
+Subject: [PATCH] Fix typo in AC_PATH_PROG for ldconfig
+
+---
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index f8cdb323..d391494d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -49,7 +49,7 @@ AC_PATH_PROG([ENV], [env], [/usr/bin/env], [/usr/bin:/bin:/sbin:/usr/sbin:/usr/l
+ AC_PATH_PROG([FAKEROOT], [fakeroot], [/usr/bin/fakeroot], [/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:$PATH])
+ AC_PATH_PROG([INSSERV], [insserv], [/sbin/insserv], [/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:$PATH])
+ AC_PATH_PROG([ISCHROOT], [ischroot], [/usr/bin/ischroot], [/usr/bin:/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH])
+-AC_PATH_PROG([LDCONFIG], [ldconfig], [/sbin/chroot], [/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:$PATH])
++AC_PATH_PROG([LDCONFIG], [ldconfig], [/sbin/ldconfig], [/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:$PATH])
+ AC_PATH_PROG([LDD], [ldd], [/usr/bin/ldd], [/usr/bin:/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH])
+ AC_PATH_PROG([LS], [ls], [/bin/ls], [/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH])
+ AC_PATH_PROG([MKFIFO], [mkfifo], [/usr/bin/mkfifo], [/usr/bin:/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH])
diff --git a/system/fakechroot/patches/autoupdate.patch b/system/fakechroot/patches/autoupdate.patch
new file mode 100644
index 0000000000..9393713497
--- /dev/null
+++ b/system/fakechroot/patches/autoupdate.patch
@@ -0,0 +1,40 @@
+--- fakechroot-2.20.1.orig/configure.ac 2019-03-22 21:02:42.000000000 +0000
++++ fakechroot-2.20.1/configure.ac 2023-02-09 00:46:10.059938547 +0000
+@@ -1,10 +1,10 @@
+-AC_PREREQ(2.64)
+-AC_INIT([fakechroot], [2.20.1], [dexter@debian.org], [fakechroot], [https://github.com/dex4er/fakechroot])
++AC_PREREQ([2.71])
++AC_INIT([fakechroot],[2.20.1],[dexter@debian.org],[fakechroot],[https://github.com/dex4er/fakechroot])
+
+ AC_CONFIG_SRCDIR([src/libfakechroot.c])
+ AC_CONFIG_AUX_DIR([build-aux])
+ AC_CONFIG_MACRO_DIR([m4])
+-AC_CONFIG_HEADER([config.h])
++AC_CONFIG_HEADERS([config.h])
+
+ AM_INIT_AUTOMAKE([1.10 foreign])
+ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+@@ -19,8 +19,8 @@ AM_PROG_AR
+ AC_PROG_CC
+ AC_PROG_MAKE_SET
+ AC_PROG_LN_S
+-AM_PROG_LIBTOOL
+-AM_PROG_NM
++LT_INIT
++LT_PATH_NM
+ LT_INIT
+
+ AC_CANONICAL_HOST
+@@ -77,7 +77,11 @@ AC_CHECK_LIB([dl], [dlsym])
+
+ # Checks for header files.
+ AC_HEADER_DIRENT
+-AC_HEADER_STDC
++# Autoupdate added the next two lines to ensure that your configure
++# script's behavior did not change. They are probably safe to remove.
++AC_CHECK_INCLUDES_DEFAULT
++AC_PROG_EGREP
++
+ AC_CHECK_HEADERS(m4_normalize([
+ alloca.h
+ dirent.h
diff --git a/system/fakechroot/patches/b42d1fb9538f680af2f31e864c555414ccba842a.patch b/system/fakechroot/patches/b42d1fb9538f680af2f31e864c555414ccba842a.patch
new file mode 100644
index 0000000000..5e4a96e709
--- /dev/null
+++ b/system/fakechroot/patches/b42d1fb9538f680af2f31e864c555414ccba842a.patch
@@ -0,0 +1,102 @@
+From b42d1fb9538f680af2f31e864c555414ccba842a Mon Sep 17 00:00:00 2001
+From: Piotr Roszatycki <piotr.roszatycki@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/NEWS.md b/NEWS.md
+index 9de12fe..f1210bf 100644
+--- a/NEWS.md
++++ b/NEWS.md
+@@ -1,5 +1,10 @@
+ # NEWS
+
++XX Xxx XXXX
++
++* UNRELEASED
++* New `statx(2)` function was added: glibc supports it since 2.28.
++
+ ## Version 2.20.1
+
+ 22 Mar 2019
+diff --git a/configure.ac b/configure.ac
+index a654edd..f8cdb32 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 d729b0e..6066345 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 0000000..524f73e
+--- /dev/null
++++ b/src/statx.c
+@@ -0,0 +1,44 @@
++/*
++ libfakechroot -- fake chroot environment
++ Copyright (c) 2010-2020 Piotr Roszatycki <dexter@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
diff --git a/system/fakechroot/patches/disable_cp.t.patch b/system/fakechroot/patches/disable_cp.t.patch
new file mode 100644
index 0000000000..1a7f90105d
--- /dev/null
+++ b/system/fakechroot/patches/disable_cp.t.patch
@@ -0,0 +1,11 @@
+t/cp.t is problematic since RHEL 6 and 7 seems to me is a problem with the test and not with coreutils version
+--- ./test/Makefile.am.orig 2023-04-06 02:04:58.107925212 +0100
++++ ./test/Makefile.am 2023-04-06 02:05:03.453907064 +0100
+@@ -7,7 +7,6 @@ TESTS = \
+ t/chroot.t \
+ t/clearenv.t \
+ t/cmd-subst.t \
+- t/cp.t \
+ t/dedotdot.t \
+ t/dladdr.t \
+ t/execlp.t \
diff --git a/system/fakechroot/patches/fix_test_on_32bits.patch b/system/fakechroot/patches/fix_test_on_32bits.patch
new file mode 100644
index 0000000000..26687f7f61
--- /dev/null
+++ b/system/fakechroot/patches/fix_test_on_32bits.patch
@@ -0,0 +1,38 @@
+removing leading / for some reason cp doesn't like it
+
+new coreutils already have -a and can replace -dp
+
+man cp
+
+-a, --archive same as -dR --preserve=all
+-d same as --no-dereference --preserve=links
+-p same as --preserve=mode,ownership,timestamps
+--- fakechroot-2.20.1/test/t/cp.t 2019-03-22 21:02:42.000000000 +0000
++++ fakechroot-2.20.1/test/t/cp.t 2022-03-04 02:07:11.511455404 +0000
+@@ -7,7 +7,7 @@ prepare 4
+
+ case "`uname -s`" in
+ Linux|KFreeBSD)
+- CP_ARGS=-dp;;
++ CP_ARGS="--preserve=all";;
+ *)
+ CP_ARGS=-a;;
+ esac
+@@ -19,13 +19,13 @@ for chroot in chroot fakechroot; do
+ else
+
+ echo 'something' > $testtree/file-$chroot
+- ln -s /file-$chroot $testtree/symlink-$chroot
++ ln -s file-$chroot $testtree/symlink-$chroot
+
+- t=`$srcdir/$chroot.sh $testtree /bin/sh -c "cp $CP_ARGS /file-$chroot /file2-$chroot; cat /file2-$chroot" 2>&1`
++ t=`$srcdir/$chroot.sh $testtree /bin/sh -c "cp $CP_ARGS file-$chroot file2-$chroot; cat /file2-$chroot" 2>&1`
+ test "$t" = "something" || not
+- ok "$chroot cp $CP_ARGS /file-$chroot /file2-$chroot:" $t
++ ok "$chroot cp $CP_ARGS file-$chroot file2-$chroot:" $t
+
+- t=`$srcdir/$chroot.sh $testtree /bin/sh -c "cp $CP_ARGS /symlink-$chroot /symlink2-$chroot; cat /symlink2-$chroot" 2>&1`
++ t=`$srcdir/$chroot.sh $testtree /bin/sh -c "cp $CP_ARGS symlink-$chroot symlink2-$chroot; cat /symlink2-$chroot" 2>&1`
+ test "$t" = "something" || not
+ ok "$chroot cp $CP_ARGS /symlink-$chroot /symlink2-$chroot:" $t
+