1552 lines
42 KiB
Diff
1552 lines
42 KiB
Diff
https://github.com/dex4er/fakechroot/pull/104
|
|
|
|
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 1/9] 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 2/9] 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 3/9] 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 4/9] 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 5/9] 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 6/9] 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 7/9] 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 543e9d3b322aeb7539b0146299feeaeb147180e0 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 8/9] add test/t/rm.t (will fail under glibc 2.34 unless
|
|
__stat64_time64 functions are wrapped)
|
|
|
|
---
|
|
test/Makefile.am | 1 +
|
|
test/t/rm.t | 25 +++++++++++++++++++++++++
|
|
2 files changed, 26 insertions(+)
|
|
create mode 100644 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 100644
|
|
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
|
|
|
|
From e9329c3b0cf98c361b96944cadeec2a1d689d2ca 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 9/9] 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..1637b9c6
|
|
--- /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
|