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@xxxxxxxxxx>, 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
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@xxxxxxxxxx> --- 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;
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:
signature.asc
Description: PGP signature