|
|
743e80 |
autofs-5.1.8 - dont use initgroups() at spawn
|
|
|
743e80 |
|
|
|
743e80 |
From: Ian Kent <raven@themaw.net>
|
|
|
743e80 |
|
|
|
743e80 |
The initgroups(3) function isn't safe to use between fork() and
|
|
|
743e80 |
exec() in a threaded program.
|
|
|
743e80 |
|
|
|
743e80 |
Using it this way often leads to a hang for even moderate work
|
|
|
743e80 |
loads.
|
|
|
743e80 |
|
|
|
743e80 |
But the getgrouplist()/setgroups() combination can be used safely
|
|
|
743e80 |
in this case and this patch changes autofs to use these (the safety
|
|
|
743e80 |
of using of setgroups() is yet to to be documented).
|
|
|
743e80 |
|
|
|
743e80 |
A large portion of the work on this patch has been contributed
|
|
|
743e80 |
by Roberto Bergantinos <rbergant@redhat.com>.
|
|
|
743e80 |
|
|
|
743e80 |
Reported-by: Roberto Bergantinos <rbergant@redhat.com>
|
|
|
743e80 |
Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()")
|
|
|
743e80 |
Signed-off-by: Roberto Bergantinos <rbergant@redhat.com>
|
|
|
743e80 |
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
|
743e80 |
---
|
|
|
743e80 |
CHANGELOG | 1 +
|
|
|
743e80 |
daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
|
|
|
743e80 |
2 files changed, 48 insertions(+), 4 deletions(-)
|
|
|
743e80 |
|
|
|
743e80 |
--- autofs-5.1.4.orig/CHANGELOG
|
|
|
743e80 |
+++ autofs-5.1.4/CHANGELOG
|
|
|
743e80 |
@@ -94,6 +94,7 @@
|
|
|
743e80 |
- fix sysconf(3) return handling.
|
|
|
743e80 |
- remove nonstrict parameter from tree_mapent_umount_offsets().
|
|
|
743e80 |
- fix handling of incorrect return from umount_ent().
|
|
|
743e80 |
+- dont use initgroups() at spawn.
|
|
|
743e80 |
|
|
|
743e80 |
xx/xx/2018 autofs-5.1.5
|
|
|
743e80 |
- fix flag file permission.
|
|
|
743e80 |
--- autofs-5.1.4.orig/daemon/spawn.c
|
|
|
743e80 |
+++ autofs-5.1.4/daemon/spawn.c
|
|
|
743e80 |
@@ -26,6 +26,7 @@
|
|
|
743e80 |
#include <sys/wait.h>
|
|
|
743e80 |
#include <sys/stat.h>
|
|
|
743e80 |
#include <sys/mount.h>
|
|
|
743e80 |
+#include <pwd.h>
|
|
|
743e80 |
|
|
|
743e80 |
#include "automount.h"
|
|
|
743e80 |
|
|
|
743e80 |
@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, uns
|
|
|
743e80 |
struct thread_stdenv_vars *tsv;
|
|
|
743e80 |
pid_t euid = 0;
|
|
|
743e80 |
gid_t egid = 0;
|
|
|
743e80 |
+ gid_t *groups = NULL;
|
|
|
743e80 |
+ gid_t *saved_groups = NULL;
|
|
|
743e80 |
+ int ngroups = 0;
|
|
|
743e80 |
+ int nsaved_groups = 0;
|
|
|
743e80 |
|
|
|
743e80 |
if (open_pipe(pipefd))
|
|
|
743e80 |
return -1;
|
|
|
743e80 |
@@ -357,6 +362,31 @@ static int do_spawn(unsigned logopt, uns
|
|
|
743e80 |
}
|
|
|
743e80 |
|
|
|
743e80 |
open_mutex_lock();
|
|
|
743e80 |
+
|
|
|
743e80 |
+ if (euid) {
|
|
|
743e80 |
+ struct passwd *pwd;
|
|
|
743e80 |
+
|
|
|
743e80 |
+ pwd = getpwuid(getuid());
|
|
|
743e80 |
+ if (!pwd)
|
|
|
743e80 |
+ fprintf(stderr,
|
|
|
743e80 |
+ "warning: getpwuid: can't get current username\n");
|
|
|
743e80 |
+ else {
|
|
|
743e80 |
+ /* get number of groups for current gid */
|
|
|
743e80 |
+ getgrouplist(pwd->pw_name, getgid(), NULL, &nsaved_groups);
|
|
|
743e80 |
+ saved_groups = malloc(nsaved_groups * sizeof(gid_t));
|
|
|
743e80 |
+
|
|
|
743e80 |
+ /* get current gid groups list */
|
|
|
743e80 |
+ getgrouplist(pwd->pw_name, getgid(), saved_groups, &nsaved_groups);
|
|
|
743e80 |
+ }
|
|
|
743e80 |
+
|
|
|
743e80 |
+ /* get number of groups of mount triggering process */
|
|
|
743e80 |
+ getgrouplist(tsv->user, egid, NULL, &ngroups);
|
|
|
743e80 |
+ groups = malloc(ngroups * sizeof(gid_t));
|
|
|
743e80 |
+
|
|
|
743e80 |
+ /* get groups list of mount triggering process */
|
|
|
743e80 |
+ getgrouplist(tsv->user, egid, groups, &ngroups);
|
|
|
743e80 |
+ }
|
|
|
743e80 |
+
|
|
|
743e80 |
f = fork();
|
|
|
743e80 |
if (f == 0) {
|
|
|
743e80 |
char **pargv = (char **) argv;
|
|
|
743e80 |
@@ -398,10 +428,13 @@ static int do_spawn(unsigned logopt, uns
|
|
|
743e80 |
if (!tsv->user)
|
|
|
743e80 |
fprintf(stderr,
|
|
|
743e80 |
"warning: can't init groups\n");
|
|
|
743e80 |
- else if (initgroups(tsv->user, egid) == -1)
|
|
|
743e80 |
- fprintf(stderr,
|
|
|
743e80 |
- "warning: initgroups: %s\n",
|
|
|
743e80 |
- strerror(errno));
|
|
|
743e80 |
+ else if (groups) {
|
|
|
743e80 |
+ if (setgroups(ngroups, groups) == -1)
|
|
|
743e80 |
+ fprintf(stderr,
|
|
|
743e80 |
+ "warning: setgroups: %s\n",
|
|
|
743e80 |
+ strerror(errno));
|
|
|
743e80 |
+ free(groups);
|
|
|
743e80 |
+ }
|
|
|
743e80 |
|
|
|
743e80 |
if (setegid(egid) == -1)
|
|
|
743e80 |
fprintf(stderr,
|
|
|
743e80 |
@@ -436,6 +469,11 @@ static int do_spawn(unsigned logopt, uns
|
|
|
743e80 |
strerror(errno));
|
|
|
743e80 |
if (pgrp >= 0)
|
|
|
743e80 |
setpgid(0, pgrp);
|
|
|
743e80 |
+ /* Reset groups for trigger of trailing mount */
|
|
|
743e80 |
+ if (euid && saved_groups) {
|
|
|
743e80 |
+ setgroups(nsaved_groups, saved_groups);
|
|
|
743e80 |
+ free(saved_groups);
|
|
|
743e80 |
+ }
|
|
|
743e80 |
|
|
|
743e80 |
/*
|
|
|
743e80 |
* The kernel leaves mount type autofs alone because
|
|
|
743e80 |
@@ -474,6 +512,11 @@ done:
|
|
|
743e80 |
pthread_sigmask(SIG_SETMASK, &tmpsig, NULL);
|
|
|
743e80 |
open_mutex_unlock();
|
|
|
743e80 |
|
|
|
743e80 |
+ if (groups)
|
|
|
743e80 |
+ free(groups);
|
|
|
743e80 |
+ if (saved_groups)
|
|
|
743e80 |
+ free(saved_groups);
|
|
|
743e80 |
+
|
|
|
743e80 |
close(pipefd[1]);
|
|
|
743e80 |
|
|
|
743e80 |
if (f < 0) {
|