zsh-workers
 help / color / mirror / code / Atom feed
* [BUG] With --disable-dynamic-nss, not all functions calls are protected
@ 2021-09-08  1:12 Vincent Lefevre
  2021-09-15 14:31 ` Axel Beckert
  0 siblings, 1 reply; 17+ messages in thread
From: Vincent Lefevre @ 2021-09-08  1:12 UTC (permalink / raw)
  To: zsh-workers; +Cc: 993843

[Posted to zsh-workers, with a Cc to the Debian bug.]

While looking at Debian bug 993843

  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993843
  (zsh-static segfaults immediately)

I can notice the following warnings:

gcc -static   -o zsh main.o  `cat stamp-modobjs`   -lgdbm -lpcre -lcap -lncursesw -ltinfo -ltinfo -lrt -lm  -lc
/usr/bin/ld: options.o: in function `dosetopt':
./obj-static/Src/../../Src/options.c:830: warning: Using 'initgroups' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: Modules/parameter.o: in function `get_all_groups':
./obj-static/Src/Modules/../../../Src/Modules/parameter.c:2058: warning: Using 'getgrgid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: Modules/files.o: in function `bin_chown':
./obj-static/Src/Modules/../../../Src/Modules/files.c:763: warning: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: params.o: in function `usernamesetfn':
./obj-static/Src/../../Src/params.c:4420: warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: options.o: in function `dosetopt':
./obj-static/Src/../../Src/options.c:822: warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

This is exactly the issue we are seeing in Debian: zsh-static
segfaults after upgrading glibc, and this issue disappears
after rebuilding zsh-static with the new glibc. And I could
see in the strace output that the shared C library libc.so.6
is read, while zsh-static should entirely be static.

However, --disable-dynamic-nss is used to build zsh-static,
so that the above functions should not be called.

I can see that Src/zsh_system.h has

#if defined(HAVE_INITGROUPS) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_INITGROUPS
#endif

#if defined(HAVE_GETGRGID) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETGRGID
#endif

#if defined(HAVE_GETGRNAM) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETGRNAM
#endif

#if defined(HAVE_GETPWENT) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETPWENT
#endif

#if defined(HAVE_GETPWNAM) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETPWNAM
#endif

#if defined(HAVE_GETPWUID) && !defined(DISABLE_DYNAMIC_NSS)
# define USE_GETPWUID
#endif

But concerning the first warning, Src/options.c contains

# ifdef HAVE_INITGROUPS

I suppose that the test should have been

# ifdef USE_INITGROUPS

like in Src/params.c, which has

# ifdef USE_INITGROUPS
        initgroups(x, pswd->pw_gid);
# endif

I suspect that there is the same issue with the other warnings.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-08  1:12 [BUG] With --disable-dynamic-nss, not all functions calls are protected Vincent Lefevre
@ 2021-09-15 14:31 ` Axel Beckert
  2021-09-15 19:13   ` Bart Schaefer
  0 siblings, 1 reply; 17+ messages in thread
From: Axel Beckert @ 2021-09-15 14:31 UTC (permalink / raw)
  To: zsh-workers, 993843


[-- Attachment #1.1: Type: text/plain, Size: 2143 bytes --]

Hi,

Vincent Lefevre wrote:
> I can notice the following warnings:
> 
> gcc -static   -o zsh main.o  `cat stamp-modobjs`   -lgdbm -lpcre -lcap -lncursesw -ltinfo -ltinfo -lrt -lm  -lc
> /usr/bin/ld: options.o: in function `dosetopt':
> ./obj-static/Src/../../Src/options.c:830: warning: Using 'initgroups' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
[...]
> I can see that Src/zsh_system.h has
> 
> #if defined(HAVE_INITGROUPS) && !defined(DISABLE_DYNAMIC_NSS)
> # define USE_INITGROUPS
> #endif
> 
> #if defined(HAVE_GETGRGID) && !defined(DISABLE_DYNAMIC_NSS)
> # define USE_GETGRGID
> #endif
[…]
> 
> But concerning the first warning, Src/options.c contains
> 
> # ifdef HAVE_INITGROUPS
> 
> I suppose that the test should have been
> 
> # ifdef USE_INITGROUPS
> 
> like in Src/params.c, which has
> 
> # ifdef USE_INITGROUPS
>         initgroups(x, pswd->pw_gid);
> # endif
> 
> I suspect that there is the same issue with the other warnings.

Not exactly. I tried to go down this route with the attached patch,
and it indeed fixes all the "Using '[…] in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking" warnings.

But copying zsh-static on a system with a different libc6 version
still segfaults, so this patch might be necessary but not sufficient.

Last line is:

  zsh-static: dl-call-libc-early-init.c:37: _dl_call_libc_early_init: Assertion `sym != NULL' failed.

So the attached patch is at least INCOMPLETE and only thought as base
for further debugging, not (yet) for inclusion in git.

Full strace of a run of zsh-static compiled with the attached patch on
Debian Unstable (glibc 2.32) and run on Debian 11 Bullseye (glibc
2.31) attached, too.

		Regards, Axel
-- 
 ,''`.  |  Axel Beckert <abe@debian.org>, https://people.debian.org/~abe/
: :' :  |  Debian Developer, ftp.ch.debian.org Admin
`. `'   |  4096R: 2517 B724 C5F6 CA99 5329  6E61 2FF9 CD59 6126 16B5
  `-    |  1024D: F067 EA27 26B9 C3FC 1486  202E C09E 1D89 9593 0EDE

[-- Attachment #1.2: make-zsh-static-really-static-#993843.patch --]
[-- Type: text/x-diff, Size: 4662 bytes --]

Description: Try to fix dynamic linking with zsh-static and resulting segfaults on libc updates
Bug-Debian: https://bugs.debian.org/993843
Bug: https://zsh.org/workers/49392
Author: Axel Beckert <abe@debian.org>

--- a/Src/hashnameddir.c
+++ b/Src/hashnameddir.c
@@ -178,7 +178,7 @@
 	    /* Using NIS or NIS+ didn't add any user directories. This seems
 	     * fishy, so we fall back to using getpwent(). If we don't have
 	     * that, we only use the passwd file. */
-#ifdef HAVE_GETPWENT
+#ifdef USE_GETPWENT
 	    struct passwd *pw;
 
 	    setpwent();
@@ -190,7 +190,7 @@
 
 	    endpwent();
 	    usepwf = 0;
-#endif /* HAVE_GETPWENT */
+#endif /* USE_GETPWENT */
 	}
 	if (usepwf) {
 	    /* Don't forget the non-NIS matches from the flat passwd file */
@@ -229,7 +229,7 @@
 	    adduserdir(pw->pw_name, pw->pw_dir, ND_USERNAME, 1);
 
 	endpwent();
-#endif /* HAVE_GETPWENT */
+#endif /* USE_GETPWENT */
 #endif
 	allusersadded = 1;
     }
--- a/Src/options.c
+++ b/Src/options.c
@@ -807,7 +807,7 @@
 	    return -1;
 	}
 
-# ifdef HAVE_INITGROUPS
+# ifdef USE_INITGROUPS
 	/* Set the supplementary groups list.
 	 *
 	 * Note that on macOS, FreeBSD, and possibly some other platforms,
--- a/Src/params.c
+++ b/Src/params.c
@@ -4414,7 +4414,7 @@
 void
 usernamesetfn(UNUSED(Param pm), char *x)
 {
-#if defined(HAVE_SETUID) && defined(HAVE_GETPWNAM)
+#if defined(HAVE_SETUID) && defined(USE_GETPWNAM)
     struct passwd *pswd;
 
     if (x && (pswd = getpwnam(x)) && (pswd->pw_uid != cached_uid)) {
@@ -4431,7 +4431,7 @@
 	    cached_uid = pswd->pw_uid;
 	}
     }
-#endif /* HAVE_SETUID && HAVE_GETPWNAM */
+#endif /* HAVE_SETUID && USE_GETPWNAM */
     zsfree(x);
 }
 
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1115,7 +1115,7 @@
 char *
 get_username(void)
 {
-#ifdef HAVE_GETPWUID
+#ifdef USE_GETPWUID
     struct passwd *pswd;
     uid_t current_uid;
 
@@ -1128,9 +1128,9 @@
 	else
 	    cached_username = ztrdup("");
     }
-#else /* !HAVE_GETPWUID */
+#else /* !USE_GETPWUID */
     cached_uid = getuid();
-#endif /* !HAVE_GETPWUID */
+#endif /* !USE_GETPWUID */
     return cached_username;
 }
 
@@ -1306,7 +1306,7 @@
 	return str;
     }
 
-#ifdef HAVE_GETPWNAM
+#ifdef USE_GETPWNAM
     {
 	/* Retrieve an entry from the password table/database for this user. */
 	struct passwd *pw;
@@ -1322,7 +1322,7 @@
 		return dupstring(pw->pw_dir);
 	}
     }
-#endif /* HAVE_GETPWNAM */
+#endif /* USE_GETPWNAM */
 
     /* There are no more possible sources of directory names, so give up. */
     return NULL;
--- a/Src/Modules/stat.c
+++ b/Src/Modules/stat.c
@@ -137,13 +137,13 @@
 	    strcat(outbuf, " (");
     }
     if (flags & STF_STRING) {
-#ifdef HAVE_GETPWUID
+#ifdef USE_GETPWUID
 	struct passwd *pwd;
 	pwd = getpwuid(uid);
 	if (pwd)
 	    strcat(outbuf, pwd->pw_name);
 	else
-#endif /* !HAVE_GETPWUID */
+#endif /* !USE_GETPWUID */
 	{
 	    char *optr;
 	    for (optr = outbuf; *optr; optr++)
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -2055,7 +2055,9 @@
 
     /* Get group names */
     for (gaptr = gs->array; gaptr < gs->array + gs->num; gaptr++) {
+#ifdef USE_GETGRGID
 	grptr = getgrgid(gaptr->gid);
+#endif /* USE_GETGRGID */
 	if (!grptr) {
 	    return NULL;
 	}
--- a/Src/Modules/files.c
+++ b/Src/Modules/files.c
@@ -734,6 +734,7 @@
 	struct passwd *pwd;
 	if(end)
 	    *end = 0;
+#ifdef USE_GETPWNAM
 	pwd = getpwnam(p);
 	if(pwd)
 	    chm.uid = pwd->pw_uid;
@@ -746,20 +747,35 @@
 		return 1;
 	    }
 	}
+#else /* !USE_GETPWNAM */
+	zwarnnam(nam, "%s: getpwnam not usable in static build", p);
+	free(uspec);
+	return 1;
+#endif /* !USE_GETPWNAM */
 	if(end) {
 	    p = end+1;
 	    if(!*p) {
+#ifdef USE_GETPWUID
 		if(!pwd && !(pwd = getpwuid(chm.uid))) {
 		    zwarnnam(nam, "%s: no such user", uspec);
 		    free(uspec);
 		    return 1;
 		}
+#else /* !USE_GETPWUID */
+                if(!pwd) {
+		    zwarnnam(nam, "%s: getpwuid not usable in static build",
+			     uspec);
+		    free(uspec);
+		    return 1;
+		}
+#endif /* !USE_GETPWUID */
 		chm.gid = pwd->pw_gid;
 	    } else if(p[0] == ':' && !p[1]) {
 		chm.gid = -1;
 	    } else {
 		struct group *grp;
 		dogroup:
+#ifdef USE_GETGRNAM
 		grp = getgrnam(p);
 		if(grp)
 		    chm.gid = grp->gr_gid;
@@ -772,6 +788,11 @@
 			return 1;
 		    }
 		}
+#else /* !USE_GETGRNAM */
+		zwarnnam(nam, "%s: getgrnam not usable in static build", p);
+		free(uspec);
+		return 1;
+#endif /* !USE_GETGRNAM */
 	    }
 	 } else
 	    chm.gid = -1;

[-- Attachment #1.3: zsh-static-still-segfaults.strace --]
[-- Type: text/plain, Size: 8360 bytes --]

execve("tmp/zsh-static", ["tmp/zsh-static"], 0x7fffde861e50 /* 53 vars */) = 0
brk(NULL)                               = 0xea9000
brk(0xea9e00)                           = 0xea9e00
arch_prctl(ARCH_SET_FS, 0xea9400)       = 0
uname({sysname="Linux", nodename="emehari", ...}) = 0
readlink("/proc/self/exe", "/home/abe/tmp/zsh-static", 4096) = 24
brk(0xecae00)                           = 0xecae00
brk(0xecb000)                           = 0xecb000
mprotect(0x642000, 32768, PROT_READ)    = 0
prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1
prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3726656, ...}) = 0
mmap(NULL, 3726656, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8581aba000
close(3)                                = 0
prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=4*1024, rlim_max=4*1024}) = 0
getuid()                                = 1000
geteuid()                               = 1000
getgid()                                = 1000
getegid()                               = 1000
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
readlink("/proc/self/fd/0", "/dev/pts/0", 4095) = 10
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
openat(AT_FDCWD, "/dev/pts/0", O_RDWR|O_NOCTTY) = 3
fcntl(3, F_DUPFD, 10)                   = 10
close(3)                                = 0
fcntl(10, F_GETFD)                      = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
fcntl(10, F_GETFL)                      = 0x8002 (flags O_RDWR|O_LARGEFILE)
ioctl(10, TCGETS, {B38400 opost isig icanon echo ...}) = 0
getpid()                                = 32389
getpgrp()                               = 32386
getpgrp()                               = 32386
rt_sigprocmask(SIG_BLOCK, [TSTP TTIN TTOU], [], 8) = 0
ioctl(10, TIOCGPGRP, [32386])           = 0
setpgid(0, 0)                           = 0
ioctl(10, TIOCSPGRP, [32389])           = 0
rt_sigprocmask(SIG_SETMASK, [], [TSTP TTIN TTOU], 8) = 0
pipe([3, 4])                            = 0
dup(0)                                  = 5
dup(0)                                  = 6
dup(0)                                  = 7
dup(0)                                  = 8
dup(0)                                  = 9
getppid()                               = 32386
getpid()                                = 32389
getuid()                                = 1000
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat(".", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat("/home/abe", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat(".", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8581ab6000
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=27002, ...}) = 0
mmap(NULL, 27002, PROT_READ, MAP_SHARED, 11, 0) = 0x7f8581aaf000
close(11)                               = 0
uname({sysname="Linux", nodename="emehari", ...}) = 0
openat(AT_FDCWD, "/proc/self/loginuid", O_RDONLY) = 11
read(11, "1000", 12)                    = 4
close(11)                               = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 11
connect(11, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(11)                               = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 11
connect(11, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(11)                               = 0
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=494, ...}) = 0
read(11, "# /etc/nsswitch.conf\n#\n# Example"..., 4096) = 494
read(11, "", 4096)                      = 0
close(11)                               = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=161344, ...}) = 0
mmap(NULL, 161344, PROT_READ, MAP_PRIVATE, 11, 0) = 0x7f8581a87000
close(11)                               = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 11
read(11, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0003\0\0\0\0\0\0"..., 832) = 832
fstat(11, {st_mode=S_IFREG|0644, st_size=51696, ...}) = 0
mmap(NULL, 79672, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 11, 0) = 0x7f8581a73000
mmap(0x7f8581a76000, 28672, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x3000) = 0x7f8581a76000
mmap(0x7f8581a7d000, 8192, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0xa000) = 0x7f8581a7d000
mmap(0x7f8581a7f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0xb000) = 0x7f8581a7f000
mmap(0x7f8581a81000, 22328, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8581a81000
close(11)                               = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 11
read(11, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@n\2\0\0\0\0\0"..., 832) = 832
fstat(11, {st_mode=S_IFREG|0755, st_size=1839792, ...}) = 0
mmap(NULL, 1852680, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 11, 0) = 0x7f85818ae000
mprotect(0x7f85818d3000, 1662976, PROT_NONE) = 0
mmap(0x7f85818d3000, 1355776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x25000) = 0x7f85818d3000
mmap(0x7f8581a1e000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x170000) = 0x7f8581a1e000
mmap(0x7f8581a69000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x1ba000) = 0x7f8581a69000
mmap(0x7f8581a6f000, 13576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8581a6f000
close(11)                               = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", O_RDONLY|O_CLOEXEC) = 11
read(11, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\20\0\0\0\0\0\0"..., 832) = 832
fstat(11, {st_mode=S_IFREG|0755, st_size=177928, ...}) = 0
mmap(NULL, 180600, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 11, 0) = 0x7f8581881000
mprotect(0x7f8581882000, 167936, PROT_NONE) = 0
mmap(0x7f8581882000, 131072, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x1000) = 0x7f8581882000
mmap(0x7f85818a2000, 32768, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x21000) = 0x7f85818a2000
mmap(0x7f85818ab000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x29000) = 0x7f85818ab000
mmap(0x7f85818ad000, 376, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f85818ad000
close(11)                               = 0
mprotect(0x7f85818ab000, 4096, PROT_READ) = 0
mprotect(0x7f8581a69000, 12288, PROT_READ) = 0
mprotect(0x7f8581a7f000, 4096, PROT_READ) = 0
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=2996, ...}) = 0
read(11, "# Locale name alias data base.\n#"..., 4096) = 2996
read(11, "", 4096)                      = 0
close(11)                               = 0
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "zsh-static: dl-call-libc-early-i"..., 100) = 100
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8581880000
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
getpid()                                = 32389
gettid()                                = 32389
tgkill(32389, 32389, SIGABRT)           = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=32389, si_uid=1000} ---
+++ killed by SIGABRT (core dumped) +++

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-15 14:31 ` Axel Beckert
@ 2021-09-15 19:13   ` Bart Schaefer
  2021-09-16  7:37     ` Jun T
  0 siblings, 1 reply; 17+ messages in thread
From: Bart Schaefer @ 2021-09-15 19:13 UTC (permalink / raw)
  To: Zsh hackers list, 993843

On Wed, Sep 15, 2021 at 7:32 AM Axel Beckert <abe@debian.org> wrote:
>
> But copying zsh-static on a system with a different libc6 version
> still segfaults, so this patch might be necessary but not sufficient.
>
> Last line is:
>
>   zsh-static: dl-call-libc-early-init.c:37: _dl_call_libc_early_init: Assertion `sym != NULL' failed.

Based on the strace, my guess would be that getrlimit() is what's
attempting to link to the dynamic library.  This is based on the
success of the uname() call and on what does NOT appear in the
subsequent trace output.  If getrlimit() does have this effect, it's
possible that getrusage() will as well.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-15 19:13   ` Bart Schaefer
@ 2021-09-16  7:37     ` Jun T
  2021-09-16 12:10       ` Axel Beckert
  0 siblings, 1 reply; 17+ messages in thread
From: Jun T @ 2021-09-16  7:37 UTC (permalink / raw)
  To: zsh-workers


> 2021/09/16 4:13、Bart Schaefer <schaefer@brasslantern.com> wrote:

> Based on the strace, my guess would be that getrlimit() is what's
> attempting to link to the dynamic library.  This is based on the
> success of the uname() call and on what does NOT appear in the
> subsequent trace output.

Probably getrlimit() is implemented by prlimit64() that appears
in the strace log, I guess.

Modules/tcp.c uses
gethostbyname2(), gethostbyadr(), getservbyname()
that are NSS-functions?

How about disabling the tcp module by setting
link=no
in config.modules, for the module name=zsh/net/tcp?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-16  7:37     ` Jun T
@ 2021-09-16 12:10       ` Axel Beckert
  2021-09-16 16:48         ` Bart Schaefer
  0 siblings, 1 reply; 17+ messages in thread
From: Axel Beckert @ 2021-09-16 12:10 UTC (permalink / raw)
  To: zsh-workers

Hi Jun,

On Thu, Sep 16, 2021 at 04:37:31PM +0900, Jun T wrote:
> > Based on the strace, my guess would be that getrlimit() is what's
> > attempting to link to the dynamic library.  This is based on the
> > success of the uname() call and on what does NOT appear in the
> > subsequent trace output.
> 
> Probably getrlimit() is implemented by prlimit64() that appears
> in the strace log, I guess.
> 
> Modules/tcp.c uses
> gethostbyname2(), gethostbyadr(), getservbyname()
> that are NSS-functions?
> 
> How about disabling the tcp module by setting
> link=no
> in config.modules, for the module name=zsh/net/tcp?

Doesn't seem to suffice as my test builds for that already have

  name=zsh/net/tcp modfile=Src/Modules/tcp.mdd link=no auto=yes load=no functions=Functions/TCP/*

in config.modules.

		Kind regards, Axel
-- 
PGP: 2FF9CD59612616B5      /~\  Plain Text Ribbon Campaign, http://arc.pasp.de/
Mail: abe@deuxchevaux.org  \ /  Say No to HTML in E-Mail and Usenet
Mail+Jabber: abe@noone.org  X
https://axel.beckert.ch/   / \  I love long mails: https://email.is-not-s.ms/


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-16 12:10       ` Axel Beckert
@ 2021-09-16 16:48         ` Bart Schaefer
  2021-09-16 18:21           ` Jun. T
  0 siblings, 1 reply; 17+ messages in thread
From: Bart Schaefer @ 2021-09-16 16:48 UTC (permalink / raw)
  To: Zsh hackers list

> > > Based on the strace, my guess would be that getrlimit() is what's
> > > attempting to link to the dynamic library.  This is based on the
> > > success of the uname() call and on what does NOT appear in the
> > > subsequent trace output.
> >
> > Probably getrlimit() is implemented by prlimit64() that appears
> > in the strace log, I guess.

Hmm.  There are two calls to uname() in the strace.  There are only
two places in the source code that might call uname(), both happen via
createparamtable(), and createparamtable() is called from setupvals()
before it calls getrlimit() to populate the limits array.  Yet the two
uname() calls are one before prlimit64() and one after, so if prlimit
== getrlimit, I can't find a code flow that matches the order of
events in the strace.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-16 16:48         ` Bart Schaefer
@ 2021-09-16 18:21           ` Jun. T
  2021-09-16 18:34             ` Axel Beckert
  2021-09-17  1:23             ` Jun T
  0 siblings, 2 replies; 17+ messages in thread
From: Jun. T @ 2021-09-16 18:21 UTC (permalink / raw)
  To: zsh-workers


> 2021/09/17 1:48, Bart Schaefer <schaefer@brasslantern.com> wrote:
> 
> Hmm.  There are two calls to uname() in the strace.

Sorry, I missed the second one.
The first one is before
readlink("/proc/self/exe", "/home/abe/tmp/zsh-static", 4096)
and I guess it is not from zsh code.

So I think the second one is from createparamtable(),
and createparamtable() seems to have finished, but getrlimit() are not
called, as you pointed out.

But it is not be probable that getrlimit(0 = RLIMIT_CPU) uses NSS.
(prlimit64() has succeeded for RLIMIT_NOFILE)

Is adjustwinsize() called? If it is called, ioctl() should be in
strace log?


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-16 18:21           ` Jun. T
@ 2021-09-16 18:34             ` Axel Beckert
  2021-09-16 22:01               ` Bart Schaefer
  2021-09-17  1:23             ` Jun T
  1 sibling, 1 reply; 17+ messages in thread
From: Axel Beckert @ 2021-09-16 18:34 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 868 bytes --]

Hi,

On Fri, Sep 17, 2021 at 03:21:43AM +0900, Jun. T wrote:
> > Hmm.  There are two calls to uname() in the strace.
> 
> Sorry, I missed the second one.
> The first one is before
> readlink("/proc/self/exe", "/home/abe/tmp/zsh-static", 4096)
> and I guess it is not from zsh code.

Sorry, I forgot to use "-f" and my zshrc is using grml's zshrc as well
as zsh-syntax-highlighting. New strace attached.

Then again, they differ only a few bytes in size
and seemingly only in pids and hex addresses wrt. to their contents.
So I assume the crash happens even before my .zshrc was loaded.

		Kind regards, Axel
-- 
PGP: 2FF9CD59612616B5      /~\  Plain Text Ribbon Campaign, http://arc.pasp.de/
Mail: abe@deuxchevaux.org  \ /  Say No to HTML in E-Mail and Usenet
Mail+Jabber: abe@noone.org  X
https://axel.beckert.ch/   / \  I love long mails: https://email.is-not-s.ms/

[-- Attachment #2: zsh-static-dash-f.strace --]
[-- Type: text/plain, Size: 8370 bytes --]

execve("tmp/zsh-static", ["tmp/zsh-static", "-f"], 0x7ffdcb1ffbf8 /* 53 vars */) = 0
brk(NULL)                               = 0x10ef000
brk(0x10efe00)                          = 0x10efe00
arch_prctl(ARCH_SET_FS, 0x10ef400)      = 0
uname({sysname="Linux", nodename="emehari", ...}) = 0
readlink("/proc/self/exe", "/home/abe/tmp/zsh-static", 4096) = 24
brk(0x1110e00)                          = 0x1110e00
brk(0x1111000)                          = 0x1111000
mprotect(0x642000, 32768, PROT_READ)    = 0
prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1
prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3726656, ...}) = 0
mmap(NULL, 3726656, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f642899d000
close(3)                                = 0
prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=4*1024, rlim_max=4*1024}) = 0
getuid()                                = 1000
geteuid()                               = 1000
getgid()                                = 1000
getegid()                               = 1000
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
readlink("/proc/self/fd/0", "/dev/pts/0", 4095) = 10
stat("/dev/pts/0", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
openat(AT_FDCWD, "/dev/pts/0", O_RDWR|O_NOCTTY) = 3
fcntl(3, F_DUPFD, 10)                   = 10
close(3)                                = 0
fcntl(10, F_GETFD)                      = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
fcntl(10, F_GETFL)                      = 0x8002 (flags O_RDWR|O_LARGEFILE)
ioctl(10, TCGETS, {B38400 opost isig icanon echo ...}) = 0
getpid()                                = 28930
getpgrp()                               = 28927
getpgrp()                               = 28927
rt_sigprocmask(SIG_BLOCK, [TSTP TTIN TTOU], [], 8) = 0
ioctl(10, TIOCGPGRP, [28927])           = 0
setpgid(0, 0)                           = 0
ioctl(10, TIOCSPGRP, [28930])           = 0
rt_sigprocmask(SIG_SETMASK, [], [TSTP TTIN TTOU], 8) = 0
pipe([3, 4])                            = 0
dup(0)                                  = 5
dup(0)                                  = 6
dup(0)                                  = 7
dup(0)                                  = 8
dup(0)                                  = 9
getppid()                               = 28927
getpid()                                = 28930
getuid()                                = 1000
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat(".", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat("/home/abe", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat(".", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
mmap(NULL, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6428999000
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=27002, ...}) = 0
mmap(NULL, 27002, PROT_READ, MAP_SHARED, 11, 0) = 0x7f6428992000
close(11)                               = 0
uname({sysname="Linux", nodename="emehari", ...}) = 0
openat(AT_FDCWD, "/proc/self/loginuid", O_RDONLY) = 11
read(11, "1000", 12)                    = 4
close(11)                               = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 11
connect(11, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(11)                               = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 11
connect(11, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(11)                               = 0
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=494, ...}) = 0
read(11, "# /etc/nsswitch.conf\n#\n# Example"..., 4096) = 494
read(11, "", 4096)                      = 0
close(11)                               = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=161344, ...}) = 0
mmap(NULL, 161344, PROT_READ, MAP_PRIVATE, 11, 0) = 0x7f642896a000
close(11)                               = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 11
read(11, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0003\0\0\0\0\0\0"..., 832) = 832
fstat(11, {st_mode=S_IFREG|0644, st_size=51696, ...}) = 0
mmap(NULL, 79672, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 11, 0) = 0x7f6428956000
mmap(0x7f6428959000, 28672, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x3000) = 0x7f6428959000
mmap(0x7f6428960000, 8192, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0xa000) = 0x7f6428960000
mmap(0x7f6428962000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0xb000) = 0x7f6428962000
mmap(0x7f6428964000, 22328, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6428964000
close(11)                               = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 11
read(11, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@n\2\0\0\0\0\0"..., 832) = 832
fstat(11, {st_mode=S_IFREG|0755, st_size=1839792, ...}) = 0
mmap(NULL, 1852680, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 11, 0) = 0x7f6428791000
mprotect(0x7f64287b6000, 1662976, PROT_NONE) = 0
mmap(0x7f64287b6000, 1355776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x25000) = 0x7f64287b6000
mmap(0x7f6428901000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x170000) = 0x7f6428901000
mmap(0x7f642894c000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x1ba000) = 0x7f642894c000
mmap(0x7f6428952000, 13576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6428952000
close(11)                               = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2", O_RDONLY|O_CLOEXEC) = 11
read(11, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\20\0\0\0\0\0\0"..., 832) = 832
fstat(11, {st_mode=S_IFREG|0755, st_size=177928, ...}) = 0
mmap(NULL, 180600, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 11, 0) = 0x7f6428764000
mprotect(0x7f6428765000, 167936, PROT_NONE) = 0
mmap(0x7f6428765000, 131072, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x1000) = 0x7f6428765000
mmap(0x7f6428785000, 32768, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x21000) = 0x7f6428785000
mmap(0x7f642878e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 11, 0x29000) = 0x7f642878e000
mmap(0x7f6428790000, 376, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6428790000
close(11)                               = 0
mprotect(0x7f642878e000, 4096, PROT_READ) = 0
mprotect(0x7f642894c000, 12288, PROT_READ) = 0
mprotect(0x7f6428962000, 4096, PROT_READ) = 0
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 11
fstat(11, {st_mode=S_IFREG|0644, st_size=2996, ...}) = 0
read(11, "# Locale name alias data base.\n#"..., 4096) = 2996
read(11, "", 4096)                      = 0
close(11)                               = 0
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "zsh-static: dl-call-libc-early-i"..., 100) = 100
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6428763000
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
getpid()                                = 28930
gettid()                                = 28930
tgkill(28930, 28930, SIGABRT)           = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=28930, si_uid=1000} ---
+++ killed by SIGABRT (core dumped) +++

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-16 18:34             ` Axel Beckert
@ 2021-09-16 22:01               ` Bart Schaefer
  0 siblings, 0 replies; 17+ messages in thread
From: Bart Schaefer @ 2021-09-16 22:01 UTC (permalink / raw)
  To: Zsh hackers list

On Thu, Sep 16, 2021 at 12:07 PM Axel Beckert <abe@deuxchevaux.org> wrote:
>
> New strace attached.

Instead of "strace", can you load this into "gdb" and "run -f" ?


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-16 18:21           ` Jun. T
  2021-09-16 18:34             ` Axel Beckert
@ 2021-09-17  1:23             ` Jun T
  2021-09-17  8:45               ` Jun T
  1 sibling, 1 reply; 17+ messages in thread
From: Jun T @ 2021-09-17  1:23 UTC (permalink / raw)
  To: zsh-workers


> 2021/09/17 3:21, Jun. T <takimoto-j@kba.biglobe.ne.jp> wrote:
> 
> So I think the second one is from createparamtable(),
> and createparamtable() seems to have finished,

Sorry, maybe createparamtable() has not finished.

I guess the problem is getlogin() called from createparamtable().

#line 847 in params.c (of current git HEAD).


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-17  1:23             ` Jun T
@ 2021-09-17  8:45               ` Jun T
  2021-09-17 13:44                 ` Axel Beckert
  2021-09-17 15:02                 ` Bart Schaefer
  0 siblings, 2 replies; 17+ messages in thread
From: Jun T @ 2021-09-17  8:45 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 5923 bytes --]


> 2021/09/17 10:23, Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
> 
> I guess the problem is getlogin() called from createparamtable().

Yes, this can be confirmed by statically linking a test program
(just call getlogin() and exit). I _hope_ there are no other places
where NSS-functions are indirectly called.

Revised the Axel's patch (also attached a file):

params.c:
do not call getlogin()

Modules/parameter.c:
Special parameter $usergroups can't be supported without NSS.
So the possibilities are:
(1) issue an error message when user try to use $usergroups
(2) do not issue an error but the parameter exists
(3) remove the parameter (remove from the table partab[])
The patch below uses (1), but I have no idea which is the best.

hashnameddir.c, options.c, utils.c:
HAVE_xxx --> USE_xxx (same as the Axel's patch)

Modules/{stat.c,files.c}:
These (and tcp.c, zftp.c) use NSS but are not patched since they are
disabled by default in static build.


diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index ef9148d7b..b44555323 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -2011,6 +2011,9 @@ scanpmdissaliases(HashTable ht, ScanFunc func, int flags)
 /**/
 static Groupset get_all_groups(void)
 {
+#ifdef DISABLE_DYNAMIC_NSS
+    return NULL;
+#else
     Groupset gs = zhalloc(sizeof(*gs));
     Groupmap gaptr;
     gid_t *list, *lptr, egid;
@@ -2063,6 +2066,7 @@ static Groupset get_all_groups(void)
     }
 
     return gs;
+#endif /* DISABLE_DYNAMIC_NSS */
 }
 
 /* Standard hash element lookup. */
@@ -2081,7 +2085,11 @@ getpmusergroups(UNUSED(HashTable ht), const char *name)
     pm->gsu.s = &nullsetscalar_gsu;
 
     if (!gs) {
+#ifdef DISABLE_DYNAMIC_NSS
+	zerr("parameter 'usergroups' not available: NSS is disabled");
+#else
 	zerr("failed to retrieve groups for user: %e", errno);
+#endif
 	pm->u.str = dupstring("");
 	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
 	return &pm->node;
@@ -2113,7 +2121,11 @@ scanpmusergroups(UNUSED(HashTable ht), ScanFunc func, int flags)
     Groupmap gaptr;
 
     if (!gs) {
+#ifdef DISABLE_DYNAMIC_NSS
+	zerr("parameter 'usergroups' not available: NSS is disabled");
+#else
 	zerr("failed to retrieve groups for user: %e", errno);
+#endif
 	return;
     }
 
diff --git a/Src/hashnameddir.c b/Src/hashnameddir.c
index bed43d025..cbd1344ef 100644
--- a/Src/hashnameddir.c
+++ b/Src/hashnameddir.c
@@ -178,7 +178,7 @@ fillnameddirtable(UNUSED(HashTable ht))
 	    /* Using NIS or NIS+ didn't add any user directories. This seems
 	     * fishy, so we fall back to using getpwent(). If we don't have
 	     * that, we only use the passwd file. */
-#ifdef HAVE_GETPWENT
+#ifdef USE_GETPWENT
 	    struct passwd *pw;
 
 	    setpwent();
@@ -190,7 +190,7 @@ fillnameddirtable(UNUSED(HashTable ht))
 
 	    endpwent();
 	    usepwf = 0;
-#endif /* HAVE_GETPWENT */
+#endif /* USE_GETPWENT */
 	}
 	if (usepwf) {
 	    /* Don't forget the non-NIS matches from the flat passwd file */
@@ -229,7 +229,7 @@ fillnameddirtable(UNUSED(HashTable ht))
 	    adduserdir(pw->pw_name, pw->pw_dir, ND_USERNAME, 1);
 
 	endpwent();
-#endif /* HAVE_GETPWENT */
+#endif /* USE_GETPWENT */
 #endif
 	allusersadded = 1;
     }
diff --git a/Src/options.c b/Src/options.c
index 783022591..a1fe918fc 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -811,7 +811,7 @@ dosetopt(int optno, int value, int force, char *new_opts)
 	    return -1;
 	}
 
-# ifdef HAVE_INITGROUPS
+# ifdef USE_INITGROUPS
 	/* Set the supplementary groups list.
 	 *
 	 * Note that on macOS, FreeBSD, and possibly some other platforms,
diff --git a/Src/params.c b/Src/params.c
index 4f6b361f9..704aad588 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -843,9 +843,12 @@ createparamtable(void)
     setsparam("HOST", ztrdup_metafy(hostnam));
     zfree(hostnam, 256);
 
-    setsparam("LOGNAME",
-	      ztrdup_metafy((str = getlogin()) && *str ?
-			    str : cached_username));
+    setsparam("LOGNAME", ztrdup_metafy(
+#ifndef DISABLE_DYNAMIC_NSS
+			(str = getlogin()) && *str ?  str :
+#endif
+				cached_username
+			));
 
 #if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV)
     /* Copy the environment variables we are inheriting to dynamic *
@@ -4430,7 +4433,7 @@ usernamegetfn(UNUSED(Param pm))
 void
 usernamesetfn(UNUSED(Param pm), char *x)
 {
-#if defined(HAVE_SETUID) && defined(HAVE_GETPWNAM)
+#if defined(HAVE_SETUID) && defined(USE_GETPWNAM)
     struct passwd *pswd;
 
     if (x && (pswd = getpwnam(x)) && (pswd->pw_uid != cached_uid)) {
@@ -4447,7 +4450,7 @@ usernamesetfn(UNUSED(Param pm), char *x)
 	    cached_uid = pswd->pw_uid;
 	}
     }
-#endif /* HAVE_SETUID && HAVE_GETPWNAM */
+#endif /* HAVE_SETUID && USE_GETPWNAM */
     zsfree(x);
 }
 
diff --git a/Src/utils.c b/Src/utils.c
index c32741ca7..a74c8bd2c 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1119,7 +1119,7 @@ char *cached_username;
 char *
 get_username(void)
 {
-#ifdef HAVE_GETPWUID
+#ifdef USE_GETPWUID
     struct passwd *pswd;
     uid_t current_uid;
 
@@ -1132,9 +1132,9 @@ get_username(void)
 	else
 	    cached_username = ztrdup("");
     }
-#else /* !HAVE_GETPWUID */
+#else /* !USE_GETPWUID */
     cached_uid = getuid();
-#endif /* !HAVE_GETPWUID */
+#endif /* !USE_GETPWUID */
     return cached_username;
 }
 
@@ -1310,7 +1310,7 @@ getnameddir(char *name)
 	return str;
     }
 
-#ifdef HAVE_GETPWNAM
+#ifdef USE_GETPWNAM
     {
 	/* Retrieve an entry from the password table/database for this user. */
 	struct passwd *pw;
@@ -1326,7 +1326,7 @@ getnameddir(char *name)
 		return dupstring(pw->pw_dir);
 	}
     }
-#endif /* HAVE_GETPWNAM */
+#endif /* USE_GETPWNAM */
 
     /* There are no more possible sources of directory names, so give up. */
     return NULL;




[-- Attachment #2: nss.patch --]
[-- Type: application/octet-stream, Size: 4757 bytes --]

diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index ef9148d7b..b44555323 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -2011,6 +2011,9 @@ scanpmdissaliases(HashTable ht, ScanFunc func, int flags)
 /**/
 static Groupset get_all_groups(void)
 {
+#ifdef DISABLE_DYNAMIC_NSS
+    return NULL;
+#else
     Groupset gs = zhalloc(sizeof(*gs));
     Groupmap gaptr;
     gid_t *list, *lptr, egid;
@@ -2063,6 +2066,7 @@ static Groupset get_all_groups(void)
     }
 
     return gs;
+#endif /* DISABLE_DYNAMIC_NSS */
 }
 
 /* Standard hash element lookup. */
@@ -2081,7 +2085,11 @@ getpmusergroups(UNUSED(HashTable ht), const char *name)
     pm->gsu.s = &nullsetscalar_gsu;
 
     if (!gs) {
+#ifdef DISABLE_DYNAMIC_NSS
+	zerr("parameter 'usergroups' not available: NSS is disabled");
+#else
 	zerr("failed to retrieve groups for user: %e", errno);
+#endif
 	pm->u.str = dupstring("");
 	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
 	return &pm->node;
@@ -2113,7 +2121,11 @@ scanpmusergroups(UNUSED(HashTable ht), ScanFunc func, int flags)
     Groupmap gaptr;
 
     if (!gs) {
+#ifdef DISABLE_DYNAMIC_NSS
+	zerr("parameter 'usergroups' not available: NSS is disabled");
+#else
 	zerr("failed to retrieve groups for user: %e", errno);
+#endif
 	return;
     }
 
diff --git a/Src/hashnameddir.c b/Src/hashnameddir.c
index bed43d025..cbd1344ef 100644
--- a/Src/hashnameddir.c
+++ b/Src/hashnameddir.c
@@ -178,7 +178,7 @@ fillnameddirtable(UNUSED(HashTable ht))
 	    /* Using NIS or NIS+ didn't add any user directories. This seems
 	     * fishy, so we fall back to using getpwent(). If we don't have
 	     * that, we only use the passwd file. */
-#ifdef HAVE_GETPWENT
+#ifdef USE_GETPWENT
 	    struct passwd *pw;
 
 	    setpwent();
@@ -190,7 +190,7 @@ fillnameddirtable(UNUSED(HashTable ht))
 
 	    endpwent();
 	    usepwf = 0;
-#endif /* HAVE_GETPWENT */
+#endif /* USE_GETPWENT */
 	}
 	if (usepwf) {
 	    /* Don't forget the non-NIS matches from the flat passwd file */
@@ -229,7 +229,7 @@ fillnameddirtable(UNUSED(HashTable ht))
 	    adduserdir(pw->pw_name, pw->pw_dir, ND_USERNAME, 1);
 
 	endpwent();
-#endif /* HAVE_GETPWENT */
+#endif /* USE_GETPWENT */
 #endif
 	allusersadded = 1;
     }
diff --git a/Src/options.c b/Src/options.c
index 783022591..a1fe918fc 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -811,7 +811,7 @@ dosetopt(int optno, int value, int force, char *new_opts)
 	    return -1;
 	}
 
-# ifdef HAVE_INITGROUPS
+# ifdef USE_INITGROUPS
 	/* Set the supplementary groups list.
 	 *
 	 * Note that on macOS, FreeBSD, and possibly some other platforms,
diff --git a/Src/params.c b/Src/params.c
index 4f6b361f9..704aad588 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -843,9 +843,12 @@ createparamtable(void)
     setsparam("HOST", ztrdup_metafy(hostnam));
     zfree(hostnam, 256);
 
-    setsparam("LOGNAME",
-	      ztrdup_metafy((str = getlogin()) && *str ?
-			    str : cached_username));
+    setsparam("LOGNAME", ztrdup_metafy(
+#ifndef DISABLE_DYNAMIC_NSS
+			(str = getlogin()) && *str ?  str :
+#endif
+				cached_username
+			));
 
 #if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV)
     /* Copy the environment variables we are inheriting to dynamic *
@@ -4430,7 +4433,7 @@ usernamegetfn(UNUSED(Param pm))
 void
 usernamesetfn(UNUSED(Param pm), char *x)
 {
-#if defined(HAVE_SETUID) && defined(HAVE_GETPWNAM)
+#if defined(HAVE_SETUID) && defined(USE_GETPWNAM)
     struct passwd *pswd;
 
     if (x && (pswd = getpwnam(x)) && (pswd->pw_uid != cached_uid)) {
@@ -4447,7 +4450,7 @@ usernamesetfn(UNUSED(Param pm), char *x)
 	    cached_uid = pswd->pw_uid;
 	}
     }
-#endif /* HAVE_SETUID && HAVE_GETPWNAM */
+#endif /* HAVE_SETUID && USE_GETPWNAM */
     zsfree(x);
 }
 
diff --git a/Src/utils.c b/Src/utils.c
index c32741ca7..a74c8bd2c 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1119,7 +1119,7 @@ char *cached_username;
 char *
 get_username(void)
 {
-#ifdef HAVE_GETPWUID
+#ifdef USE_GETPWUID
     struct passwd *pswd;
     uid_t current_uid;
 
@@ -1132,9 +1132,9 @@ get_username(void)
 	else
 	    cached_username = ztrdup("");
     }
-#else /* !HAVE_GETPWUID */
+#else /* !USE_GETPWUID */
     cached_uid = getuid();
-#endif /* !HAVE_GETPWUID */
+#endif /* !USE_GETPWUID */
     return cached_username;
 }
 
@@ -1310,7 +1310,7 @@ getnameddir(char *name)
 	return str;
     }
 
-#ifdef HAVE_GETPWNAM
+#ifdef USE_GETPWNAM
     {
 	/* Retrieve an entry from the password table/database for this user. */
 	struct passwd *pw;
@@ -1326,7 +1326,7 @@ getnameddir(char *name)
 		return dupstring(pw->pw_dir);
 	}
     }
-#endif /* HAVE_GETPWNAM */
+#endif /* USE_GETPWNAM */
 
     /* There are no more possible sources of directory names, so give up. */
     return NULL;

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-17  8:45               ` Jun T
@ 2021-09-17 13:44                 ` Axel Beckert
  2021-09-17 13:55                   ` Roman Perepelitsa
  2021-09-17 15:02                 ` Bart Schaefer
  1 sibling, 1 reply; 17+ messages in thread
From: Axel Beckert @ 2021-09-17 13:44 UTC (permalink / raw)
  To: zsh-workers

Hi,

On Fri, Sep 17, 2021 at 05:45:37PM +0900, Jun T wrote:
> > I guess the problem is getlogin() called from createparamtable().
> 
> Yes, this can be confirmed by statically linking a test program
> (just call getlogin() and exit). I _hope_ there are no other places
> where NSS-functions are indirectly called.
> 
> Revised the Axel's patch (also attached a file):

Yay, this patch works for me! zsh-static built on Debian Unstable
(glibc 2.32) no more segfaults when copied to and executed on Debian
11 Bullseye (glibc 2.31) for me. (Just my way to test it, the issue
popped up in Debian Unstable the other way round when glibc was
upgraded from 2.31 to 2.32.)

Bart: Sorry for not providing a gdb backtrace in time. Was too tired
last night to figure out where to put Debian's debug symbols when not
installing the built packages (or to set up a fitting chroot for
testing with the built packages) for generating a backtrace with gdb.

		Kind regards, Axel
-- 
PGP: 2FF9CD59612616B5      /~\  Plain Text Ribbon Campaign, http://arc.pasp.de/
Mail: abe@deuxchevaux.org  \ /  Say No to HTML in E-Mail and Usenet
Mail+Jabber: abe@noone.org  X
https://axel.beckert.ch/   / \  I love long mails: https://email.is-not-s.ms/


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-17 13:44                 ` Axel Beckert
@ 2021-09-17 13:55                   ` Roman Perepelitsa
  2021-09-17 14:16                     ` Axel Beckert
  0 siblings, 1 reply; 17+ messages in thread
From: Roman Perepelitsa @ 2021-09-17 13:55 UTC (permalink / raw)
  To: Zsh hackers list

On Fri, Sep 17, 2021 at 3:45 PM Axel Beckert <abe@deuxchevaux.org> wrote:
>
> Hi,
>
> On Fri, Sep 17, 2021 at 05:45:37PM +0900, Jun T wrote:
> > > I guess the problem is getlogin() called from createparamtable().
> >
> > Yes, this can be confirmed by statically linking a test program
> > (just call getlogin() and exit). I _hope_ there are no other places
> > where NSS-functions are indirectly called.
> >
> > Revised the Axel's patch (also attached a file):
>
> Yay, this patch works for me! zsh-static built on Debian Unstable
> (glibc 2.32) no more segfaults when copied to and executed on Debian
> 11 Bullseye (glibc 2.31) for me.

If your goal is to create a binary that runs on any Linux x64 box
regardless of libc runtimes that may or may not be available on it,
link against musl libc. Static linking against glibc is a lost cause.
Zsh can link against musl libc out of the box. This is how I build
mine.

Roman.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-17 13:55                   ` Roman Perepelitsa
@ 2021-09-17 14:16                     ` Axel Beckert
  0 siblings, 0 replies; 17+ messages in thread
From: Axel Beckert @ 2021-09-17 14:16 UTC (permalink / raw)
  To: zsh-workers

Hi Roman,

On Fri, Sep 17, 2021 at 03:55:43PM +0200, Roman Perepelitsa wrote:
> > Yay, this patch works for me! zsh-static built on Debian Unstable
> > (glibc 2.32) no more segfaults when copied to and executed on Debian
> > 11 Bullseye (glibc 2.31) for me.
> 
> If your goal is to create a binary that runs on any Linux x64 box
> regardless of libc runtimes that may or may not be available on it,
> link against musl libc.

Thanks for that idea, but the main goal for now was to make zsh-static
survive glibc upgrades in Debian (Unstable first and foremost).

> Static linking against glibc is a lost cause.

Not the first time I've read that, yes.

> Zsh can link against musl libc out of the box. This is how I build
> mine.

I've just checked: At least bash-static, busybox-static and sash
(static by default as that's its purpose) are built against glibc in
Debian, so I'll probably stay with glibc for now in Debian's
zsh-static package.

Nevertheless thanks for that hint. Will keep it in mind in case we run
into more severe glibc issues with static builds in the future.

		Kind regards, Axel
-- 
PGP: 2FF9CD59612616B5      /~\  Plain Text Ribbon Campaign, http://arc.pasp.de/
Mail: abe@deuxchevaux.org  \ /  Say No to HTML in E-Mail and Usenet
Mail+Jabber: abe@noone.org  X
https://axel.beckert.ch/   / \  I love long mails: https://email.is-not-s.ms/


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-17  8:45               ` Jun T
  2021-09-17 13:44                 ` Axel Beckert
@ 2021-09-17 15:02                 ` Bart Schaefer
  2021-09-21  0:53                   ` Jun T
  1 sibling, 1 reply; 17+ messages in thread
From: Bart Schaefer @ 2021-09-17 15:02 UTC (permalink / raw)
  To: Jun T; +Cc: Zsh hackers list

On Fri, Sep 17, 2021 at 1:46 AM Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
>
> Special parameter $usergroups can't be supported without NSS.
> So the possibilities are:
> (1) issue an error message when user try to use $usergroups
> (2) do not issue an error but the parameter exists
> (3) remove the parameter (remove from the table partab[])
> The patch below uses (1), but I have no idea which is the best.

I think I'd go with (2) but add the new PM_DEFAULTED flag so that the
parameter is permanently unset.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-17 15:02                 ` Bart Schaefer
@ 2021-09-21  0:53                   ` Jun T
  2021-09-21  3:38                     ` Bart Schaefer
  0 siblings, 1 reply; 17+ messages in thread
From: Jun T @ 2021-09-21  0:53 UTC (permalink / raw)
  To: zsh-workers


> 2021/09/18 0:02、Bart Schaefer <schaefer@brasslantern.com>のメール:
> 
> On Fri, Sep 17, 2021 at 1:46 AM Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
>> 
>> Special parameter $usergroups can't be supported without NSS.
>> So the possibilities are:
>> (1) issue an error message when user try to use $usergroups
>> (2) do not issue an error but the parameter exists
>> (3) remove the parameter (remove from the table partab[])
>> The patch below uses (1), but I have no idea which is the best.
> 
> I think I'd go with (2) but add the new PM_DEFAULTED flag so that the
> parameter is permanently unset.

Do you suggest adding another configure flag?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [BUG] With --disable-dynamic-nss, not all functions calls are protected
  2021-09-21  0:53                   ` Jun T
@ 2021-09-21  3:38                     ` Bart Schaefer
  0 siblings, 0 replies; 17+ messages in thread
From: Bart Schaefer @ 2021-09-21  3:38 UTC (permalink / raw)
  To: Jun T; +Cc: Zsh hackers list

On Mon, Sep 20, 2021 at 5:54 PM Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
>
> > 2021/09/18 0:02、Bart Schaefer <schaefer@brasslantern.com>のメール:
> >
> > On Fri, Sep 17, 2021 at 1:46 AM Jun T <takimoto-j@kba.biglobe.ne.jp> wrote:
> >>
> >> (1) issue an error message when user try to use $usergroups
> >> (2) do not issue an error but the parameter exists
> >> The patch below uses (1), but I have no idea which is the best.
> >
> > I think I'd go with (2) but add the new PM_DEFAULTED flag so that the
> > parameter is permanently unset.
>
> Do you suggest adding another configure flag?

I was not considering that, no.

On closer examination of the patch, I see you're just changing the
error message, not adding a new case where an error might occur, so
ultimately I think it's fine the way you have already patched it.


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-09-21  3:39 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-08  1:12 [BUG] With --disable-dynamic-nss, not all functions calls are protected Vincent Lefevre
2021-09-15 14:31 ` Axel Beckert
2021-09-15 19:13   ` Bart Schaefer
2021-09-16  7:37     ` Jun T
2021-09-16 12:10       ` Axel Beckert
2021-09-16 16:48         ` Bart Schaefer
2021-09-16 18:21           ` Jun. T
2021-09-16 18:34             ` Axel Beckert
2021-09-16 22:01               ` Bart Schaefer
2021-09-17  1:23             ` Jun T
2021-09-17  8:45               ` Jun T
2021-09-17 13:44                 ` Axel Beckert
2021-09-17 13:55                   ` Roman Perepelitsa
2021-09-17 14:16                     ` Axel Beckert
2021-09-17 15:02                 ` Bart Schaefer
2021-09-21  0:53                   ` Jun T
2021-09-21  3:38                     ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).