From 511169a7154788815dc1ab1db3c30cc07fdd6440 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Mon, 30 May 2022 10:28:50 +0800 Subject: [PATCH] libnss_sss: threads stuck at sss_nss_lock from initgroups Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2087535 In threaded programs it's required to not call functions that are not async-thread safe between fork(2) and exec(3). Unfortunately initgroups(3) is not async-thread safe but is called between these two functions and it leads to automount(8) hanging. But getgroups(2) and setgroups(2) can be used for this and even though setgroups(2) is not listed as async-thread safe it is in fact safe to call here. This MR changes automount(8) to use getgroups(2)/setgroups(2) instead if initgroups(3) and testing shows that this resolves the hang problem. Resolves: rhbz#2087535 Signed-off-by: Ian Kent ikent@redhat.com --- ...s-5.1.8-dont-use-initgroups-at-spawn.patch | 131 ++++++++++++++++++ autofs.spec | 17 ++- 2 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 autofs-5.1.8-dont-use-initgroups-at-spawn.patch diff --git a/autofs-5.1.8-dont-use-initgroups-at-spawn.patch b/autofs-5.1.8-dont-use-initgroups-at-spawn.patch new file mode 100644 index 0000000..185e98f --- /dev/null +++ b/autofs-5.1.8-dont-use-initgroups-at-spawn.patch @@ -0,0 +1,131 @@ +autofs-5.1.8 - dont use initgroups() at spawn + +From: Ian Kent + +The initgroups(3) function isn't safe to use between fork() and +exec() in a threaded program. + +Using it this way often leads to a hang for even moderate work +loads. + +But the getgrouplist()/setgroups() combination can be used safely +in this case and this patch changes autofs to use these (the safety +of using of setgroups() is yet to to be documented). + +A large portion of the work on this patch has been contributed +by Roberto Bergantinos . + +Reported-by: Roberto Bergantinos +Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()") +Signed-off-by: Roberto Bergantinos +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 48 insertions(+), 4 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -101,6 +101,7 @@ + - also require TCP_REQUESTED when setting NFS port. + - bailout on rpc systemerror. + - fix nfsv4 only mounts should not use rpcbind. ++- dont use initgroups() at spawn. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/spawn.c ++++ autofs-5.1.7/daemon/spawn.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "automount.h" + +@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, uns + struct thread_stdenv_vars *tsv; + pid_t euid = 0; + gid_t egid = 0; ++ gid_t *groups = NULL; ++ gid_t *saved_groups = NULL; ++ int ngroups = 0; ++ int nsaved_groups = 0; + + if (open_pipe(pipefd)) + return -1; +@@ -357,6 +362,31 @@ static int do_spawn(unsigned logopt, uns + } + + open_mutex_lock(); ++ ++ if (euid) { ++ struct passwd *pwd; ++ ++ pwd = getpwuid(getuid()); ++ if (!pwd) ++ fprintf(stderr, ++ "warning: getpwuid: can't get current username\n"); ++ else { ++ /* get number of groups for current gid */ ++ getgrouplist(pwd->pw_name, getgid(), NULL, &nsaved_groups); ++ saved_groups = malloc(nsaved_groups * sizeof(gid_t)); ++ ++ /* get current gid groups list */ ++ getgrouplist(pwd->pw_name, getgid(), saved_groups, &nsaved_groups); ++ } ++ ++ /* get number of groups of mount triggering process */ ++ getgrouplist(tsv->user, egid, NULL, &ngroups); ++ groups = malloc(ngroups * sizeof(gid_t)); ++ ++ /* get groups list of mount triggering process */ ++ getgrouplist(tsv->user, egid, groups, &ngroups); ++ } ++ + f = fork(); + if (f == 0) { + char **pargv = (char **) argv; +@@ -398,10 +428,13 @@ static int do_spawn(unsigned logopt, uns + if (!tsv->user) + fprintf(stderr, + "warning: can't init groups\n"); +- else if (initgroups(tsv->user, egid) == -1) +- fprintf(stderr, +- "warning: initgroups: %s\n", +- strerror(errno)); ++ else if (groups) { ++ if (setgroups(ngroups, groups) == -1) ++ fprintf(stderr, ++ "warning: setgroups: %s\n", ++ strerror(errno)); ++ free(groups); ++ } + + if (setegid(egid) == -1) + fprintf(stderr, +@@ -436,6 +469,11 @@ static int do_spawn(unsigned logopt, uns + strerror(errno)); + if (pgrp >= 0) + setpgid(0, pgrp); ++ /* Reset groups for trigger of trailing mount */ ++ if (euid && saved_groups) { ++ setgroups(nsaved_groups, saved_groups); ++ free(saved_groups); ++ } + + /* + * The kernel leaves mount type autofs alone because +@@ -474,6 +512,11 @@ done: + pthread_sigmask(SIG_SETMASK, &tmpsig, NULL); + open_mutex_unlock(); + ++ if (groups) ++ free(groups); ++ if (saved_groups) ++ free(saved_groups); ++ + close(pipefd[1]); + + if (f < 0) { diff --git a/autofs.spec b/autofs.spec index f1f6dcd..fc83fb1 100644 --- a/autofs.spec +++ b/autofs.spec @@ -12,15 +12,15 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.7 -Release: 30%{?dist} +Release: 31%{?dist} Epoch: 1 License: GPLv2+ Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-2.tar.gz # patches 1 and 2 have been applied to the source tar to remove # lib/mount.x as it has an incompatible license. -Patch1: autofs-5.1.7-add-xdr_exports.patch -Patch2: autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch +#Patch1: autofs-5.1.7-add-xdr_exports.patch +#Patch2: autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch Patch3: autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch Patch4: autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch Patch5: autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch @@ -127,6 +127,8 @@ Patch100: autofs-5.1.7-also-require-TCP_REQUESTED-when-setting-NFS-port.patch Patch101: autofs-5.1.8-bailout-on-rpc-systemerror.patch Patch102: autofs-5.1.8-fix-nfsv4-only-mounts-should-not-use-rpcbind.patch +Patch103: autofs-5.1.8-dont-use-initgroups-at-spawn.patch + %if %{with_systemd} BuildRequires: systemd-units BuildRequires: systemd-devel @@ -297,6 +299,8 @@ echo %{version}-%{release} > .version %patch101 -p1 %patch102 -p1 +%patch103 -p1 + %build LDFLAGS=-Wl,-z,now %configure \ @@ -404,6 +408,13 @@ fi %dir /etc/auto.master.d %changelog +* Mon May 30 2022 Ian Kent - 1:5.1.7-31 +- bz2087535 - libnss_sss: threads stuck at sss_nss_lock from initgroups + - dont use initgroups() at spawn. + - comment out Patch1 and Patch2 since they have been merged into + the distribution tar (and so are not applied). +- Resolves: rhbz#2087535 + * Mon May 16 2022 Ian Kent - 1:5.1.7-30 - bz2084108 - autofs is slow to mount when doing lookups returns multiple entries - make NFS version check flags consistent.