Bug#993946: fakechroot: adduser fails with glibc 2.32
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 __nss_files_fope
Processed: Re: Bug#993946: fakechroot: adduser fails with glibc 2.32
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
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
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
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
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