Bug#993946: fakechroot: adduser fails with glibc 2.32

2021-09-09 Thread Johannes Schauer Marin Rodrigues
Hi,

I NMU-ed fakechroot with the patch from my last mail. The debdiff is attached.
As per devref I uploaded to DELAYED/5 in case you have objections and want to
cancel it.

Thanks!

cheers, joschdiff -Nru fakechroot-2.19/debian/changelog fakechroot-2.19/debian/changelog
--- fakechroot-2.19/debian/changelog	2021-08-17 10:58:10.0 +0200
+++ fakechroot-2.19/debian/changelog	2021-09-09 19:50:34.0 +0200
@@ -1,3 +1,10 @@
+fakechroot (2.19-3.5) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Wrap __nss_files_fopen for getpwnam in glibc >= 2.32 (closes: #993946)
+
+ -- Johannes Schauer Marin Rodrigues   Thu, 09 Sep 2021 19:50:34 +0200
+
 fakechroot (2.19-3.4) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru fakechroot-2.19/debian/patches/0001-Wrap-__nss_files_fopen-for-getpwnam-in-glibc-2.32.patch fakechroot-2.19/debian/patches/0001-Wrap-__nss_files_fopen-for-getpwnam-in-glibc-2.32.patch
--- fakechroot-2.19/debian/patches/0001-Wrap-__nss_files_fopen-for-getpwnam-in-glibc-2.32.patch	1970-01-01 01:00:00.0 +0100
+++ fakechroot-2.19/debian/patches/0001-Wrap-__nss_files_fopen-for-getpwnam-in-glibc-2.32.patch	2021-09-09 19:48:29.0 +0200
@@ -0,0 +1,112 @@
+From 14ab1b7910bf080b715d8ae846f8fc24b72823ed Mon Sep 17 00:00:00 2001
+From: Johannes Schauer Marin Rodrigues 
+Date: Thu, 9 Sep 2021 18:21:07 +0200
+Subject: [PATCH] Wrap __nss_files_fopen for getpwnam in glibc >= 2.32
+
+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.
+
+Adhemerval Zanella (azanella) argued on IRC:
+
+ > But another problem is the ship has sailed, so there are nss modules that
+ > will bind to an external symbol. And there is not much we can do about
+ > it. And since nss modules are most compat, I am not sure community will
+ > be willing to move back. I think it will be better to add the interpose
+ > logic of private symbols on fakechroot instead, it is ugly but it is
+ > better than messing even more with the nss interface.
+
+Thus, instead of changing glibc, we instead wrap __nss_files_fopen.
+---
+ configure.ac|  1 +
+ src/Makefile.am |  1 +
+ src/__nss_files_fopen.c | 60 +
+ 3 files changed, 62 insertions(+)
+ create mode 100644 src/__nss_files_fopen.c
+
+--- a/configure.ac
 b/configure.ac
+@@ -134,6 +134,7 @@ AC_CHECK_FUNCS(m4_normalize([
+ __getwd_chk
+ __lxstat
+ __lxstat64
++__nss_files_fopen
+ __open
+ __open_2
+ __open64
+--- a/src/Makefile.am
 b/src/Makefile.am
+@@ -7,6 +7,7 @@ libfakechroot_la_SOURCES = \
+ __lxstat.c \
+ __lxstat64.c \
+ __lxstat64.h \
++__nss_files_fopen.c \
+ __open.c \
+ __open64.c \
+ __open64_2.c \
+--- /dev/null
 b/src/__nss_files_fopen.c
+@@ -0,0 +1,60 @@
++/*
++libfakechroot -- fake chroot environment
++Copyright (c) 2010, 2013 Piotr Roszatycki 
++
++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 
++
++/*
++ * 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.
++ *
++ * Adhemerval Zanella (azanella) argued on IRC:
++ *
++ *  > But another problem is the ship has sailed, so there are nss modules that
++ *  > will bind to an external symbol. And there is not much we can do about
++ *  > it. And since nss modules are most compat, I am not sure community will
++ *  > be willing to move back. I think it will be better to add the interpose
++ *  > logic of private symbols on fakechroot instead, it is ugly but it is
++ *  > better than messing even more with the nss interface.
++ *
++ * Thus, instead of changing glibc, we instead wrap 

Processed: Re: Bug#993946: fakechroot: adduser fails with glibc 2.32

2021-09-09 Thread Debian Bug Tracking System
Processing control commands:

> tag -1 + patch
Bug #993946 [fakechroot] fakechroot: adduser fails with glibc 2.32
Added tag(s) patch.
> forwarded -1 https://github.com/dex4er/fakechroot/issues/97
Bug #993946 [fakechroot] fakechroot: adduser fails with glibc 2.32
Set Bug forwarded-to-address to 
'https://github.com/dex4er/fakechroot/issues/97'.

-- 
993946: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993946
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems



Bug#993946: fakechroot: adduser fails with glibc 2.32

2021-09-09 Thread Johannes Schauer Marin Rodrigues
Control: tag -1 + patch
Control: forwarded -1 https://github.com/dex4er/fakechroot/issues/97

With the help of the glibc developer Adhemerval Zanella I managed to find a
solution for this problem. The attached patch wraps __nss_files_fopen from
glibc.--- a/configure.ac
+++ b/configure.ac
@@ -165,6 +165,7 @@ AC_CHECK_FUNCS(m4_normalize([
 __getwd_chk
 __lxstat
 __lxstat64
+__nss_files_fopen
 __open
 __open_2
 __open64
--- /dev/null
+++ b/src/__nss_files_fopen.c
@@ -0,0 +1,60 @@
+/*
+libfakechroot -- fake chroot environment
+Copyright (c) 2010, 2013 Piotr Roszatycki 
+
+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 
+
+/*
+ * 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.
+ *
+ * Adhemerval Zanella (azanella) argued on IRC:
+ *
+ *  > But another problem is the ship has sailed, so there are nss modules that
+ *  > will bind to an external symbol. And there is not much we can do about
+ *  > it. And since nss modules are most compat, I am not sure community will
+ *  > be willing to move back. I think it will be better to add the interpose
+ *  > logic of private symbols on fakechroot instead, it is ugly but it is
+ *  > better than messing even more with the nss interface.
+ *
+ * Thus, instead of changing glibc, we instead wrap __nss_files_fopen.
+ *
+ */
+#ifdef HAVE___NSS_FILES_FOPEN
+
+#include 
+#include "libfakechroot.h"
+
+
+wrapper(__nss_files_fopen, FILE *, (const char * path))
+{
+char fakechroot_abspath[FAKECHROOT_PATH_MAX];
+char fakechroot_buf[FAKECHROOT_PATH_MAX];
+debug("__nss_files_fopen(\"%s\")", path);
+expand_chroot_path(path);
+return nextcall(__nss_files_fopen)(path);
+}
+
+#else
+typedef int empty_translation_unit;
+#endif
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ libfakechroot_la_SOURCES = \
 __lxstat.c \
 __lxstat64.c \
 __lxstat64.h \
+__nss_files_fopen.c \
 __open.c \
 __open64.c \
 __open64_2.c \


signature.asc
Description: signature


Bug#993946: fakechroot: adduser fails with glibc 2.32

2021-09-09 Thread Johannes Schauer Marin Rodrigues
I got a gdb backtrace for the openat syscall of /etc/passwd.

This is with glibc 2.31:

#0  __GI___open64_nocancel (file=0x77df715e "/etc/passwd", oflag=524288)
at ../sysdeps/unix/sysv/linux/open64_nocancel.c:45
#1  0x77e82185 in __GI__IO_file_open (fp=fp@entry=0x96b0, 
filename=, posix_mode=, prot=prot@entry=438, 
read_write=8, is32not64=) at fileops.c:186
#2  0x77e822aa in _IO_new_file_fopen (fp=fp@entry=0x96b0, 
filename=filename@entry=0x77df715e "/etc/passwd", mode=, 
mode@entry=0x77df7003 "rce", is32not64=is32not64@entry=1) at 
fileops.c:281
#3  0x77e75c09 in __fopen_internal (
filename=filename@entry=0x77df715e "/etc/passwd", 
mode=mode@entry=0x77df7003 "rce", is32=is32@entry=1) at iofopen.c:75
#4  0x77e75c8a in _IO_new_fopen (
filename=filename@entry=0x77df715e "/etc/passwd", 
mode=mode@entry=0x77df7003 "rce") at iofopen.c:86
#5  0x77df37a0 in internal_setent (stream=)
at nss_files/files-XXX.c:77
#6  _nss_files_getpwnam_r (name=0x7fffe38a "root", result=0x7fffdf10, 
buffer=0x92a0 "", buflen=1024, errnop=0x77fc74c0)
at nss_files/files-pwd.c:32
#7  0x77ecb4f3 in __getpwnam_r (name=0x7fffe38a "root", 
resbuf=0x7fffdf10, 
buffer=0x92a0 "", buflen=1024, result=)
at ../nss/getXXbyYY_r.c:315
#8  0x5266 in main (argc=2, argv=0x7fffe058) at test.c:30

fopen gets called here: 
https://sources.debian.org/src/glibc/2.31-17/nss/nss_files/files-XXX.c/#L77

This is with glibc 2.32:

#0  __GI___open64_nocancel (file=0x77db104f "/etc/passwd", oflag=524288)
at ../sysdeps/unix/sysv/linux/open64_nocancel.c:45
#1  0x77e369d5 in __GI__IO_file_open (fp=fp@entry=0x96b0, 
filename=, 
posix_mode=, prot=prot@entry=438, read_write=8, 
is32not64=) at fileops.c:186
#2  0x77e36afa in _IO_new_file_fopen (fp=fp@entry=0x96b0, 
filename=filename@entry=0x77db104f "/etc/passwd", mode=, 
mode@entry=0x77f3f08e "rce", 
is32not64=is32not64@entry=1) at fileops.c:281
#3  0x77e2a829 in __fopen_internal 
(filename=filename@entry=0x77db104f "/etc/passwd", 
mode=mode@entry=0x77f3f08e "rce", is32=is32@entry=1) at iofopen.c:75
#4  0x77e2a8aa in _IO_new_fopen (filename=filename@entry=0x77db104f 
"/etc/passwd", 
mode=mode@entry=0x77f3f08e "rce") at iofopen.c:86
#5  0x77ed7dbe in __GI___nss_files_fopen 
(path=path@entry=0x77db104f "/etc/passwd")
at nss_files_fopen.c:27
#6  0x77dac3cc in internal_setpwent (ent=ent@entry=0x7fffde70, 
stayopen=stayopen@entry=0, 
needent=needent@entry=0) at nss_compat/compat-pwd.c:227
#7  0x77dad76a in _nss_compat_getpwnam_r (name=0x7fffe479 "josch", 
pwd=0x7fffe020, 
buffer=0x92a0 "", buflen=1024, errnop=0x77f7c4c8) at 
nss_compat/compat-pwd.c:829
#8  0x77e801e3 in __getpwnam_r (name=0x7fffe479 "josch", 
resbuf=0x7fffe020, 
buffer=0x92a0 "", buflen=1024, result=) at 
../nss/getXXbyYY_r.c:315
#9  0x5266 in main (argc=2, argv=0x7fffe168) at test.c:30

fopen gets called here: 
https://sources.debian.org/src/glibc/2.32-2/nss/nss_files_fopen.c/#L27

But why is the fopen of 2.32 different from the one in 2.31?

signature.asc
Description: signature


Bug#993946: fakechroot: adduser fails with glibc 2.32

2021-09-08 Thread Johannes Schauer Marin Rodrigues
Quoting Johannes Schauer Marin Rodrigues (2021-09-08 13:59:02)
> since the upload of glibc 2.32 to unstable, adduser under fakechroot
> fails because it is not wrapping some library call and thus read the
> system's /etc/passwd instead of the chroot's.
> 
> Some bits from strace output:

I managed to create a more minimal reproducer for this problem:

$ perl -e 'print getpwnam("_apt")'

This is with glibc 2.31:

[pid  3889] getcwd("/tmp/chroot", 4096) = 12
[pid  3889] openat(AT_FDCWD, "/tmp/chroot/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
[pid  3889] lseek(3, 0, SEEK_CUR)   = 0
[pid  3889] fstat(3, {st_mode=S_IFREG|0644, st_size=922, ...}) = 0
[pid  3889] read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 922
[pid  3889] close(3)= 0
[pid  3889] getcwd("/tmp/chroot", 4096) = 12
[pid  3889] openat(AT_FDCWD, "/tmp/chroot/etc/shadow", O_RDONLY|O_CLOEXEC) = 3
[pid  3889] lseek(3, 0, SEEK_CUR)   = 0
[pid  3889] fstat(3, {st_mode=S_IFREG|0640, st_size=501, ...}) = 0
[pid  3889] read(3, "root:*:18878:0:9:7:::\ndaemon"..., 4096) = 501
[pid  3889] close(3)= 0

And this is with glibc 2.32:

[pid 2372761] openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
[pid 2372761] fstat(3, {st_mode=S_IFREG|0644, st_size=2902, ...}) = 0
[pid 2372761] lseek(3, 0, SEEK_SET) = 0
[pid 2372761] read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 2902
[pid 2372761] close(3)  = 0
[pid 2372761] openat(AT_FDCWD, "/etc/shadow", O_RDONLY|O_CLOEXEC) = -1 EACCES 
(Permission denied)

Curiously, with old glibc, there is an additional getcwd call before the
openat...

signature.asc
Description: signature


Bug#993946: fakechroot: adduser fails with glibc 2.32

2021-09-08 Thread Johannes Schauer Marin Rodrigues
Package: fakechroot
Version: 2.19-3.4
Severity: grave
Justification: renders package unusable

Hi,

since the upload of glibc 2.32 to unstable, adduser under fakechroot
fails because it is not wrapping some library call and thus read the
system's /etc/passwd instead of the chroot's.

Some bits from strace output:

$ adduser --force-badname --system --home /nonexistent --no-create-home _apt
[...]
[pid 2353931] openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
[pid 2353931] fstat(3, {st_mode=S_IFREG|0644, st_size=2902, ...}) = 0
[pid 2353931] lseek(3, 0, SEEK_SET) = 0
[pid 2353931] read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 2902
[pid 2353931] close(3)  = 0
[pid 2353931] openat(AT_FDCWD, "/etc/shadow", O_RDONLY|O_CLOEXEC) = -1 EACCES 
(Permission denied)
[pid 2353931] openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
[pid 2353931] fstat(3, {st_mode=S_IFREG|0644, st_size=2902, ...}) = 0
[pid 2353931] lseek(3, 0, SEEK_SET) = 0
[pid 2353931] read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 2902
[pid 2353931] close(3)  = 0
[pid 2353931] write(1, "The system user `_apt' already e"..., 48The system user 
`_apt' already exists. Exiting.
) = 48

This means that one cannot anymore create a chroot with apt using
fakechroot. Thus marking this bug as RC.

Thanks!

cheers, josch