From 55739de8b71be0f64894794fdf6b3f3d9f227ef3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Oct 2014 13:41:05 -0700 Subject: [PATCH 1/2] lib: util: Signal handling - change CatchChild() and CatchChildLeaveStatus() to return the previous handler. Bug #10831 - SIGCLD Signal handler not correctly reinstalled on old library code use - smbrun etc. https://bugzilla.samba.org/show_bug.cgi?id=10831 Signed-off-by: Jeremy Allison Reviewed-by: Martin Schwenke --- lib/util/samba_util.h | 4 ++-- lib/util/signal.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index f4216d8..c6eb349 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -107,12 +107,12 @@ void (*CatchSignal(int signum,void (*handler)(int )))(int); /** Ignore SIGCLD via whatever means is necessary for this OS. **/ -void CatchChild(void); +void (*CatchChild(void))(int); /** Catch SIGCLD but leave the child around so it's status can be reaped. **/ -void CatchChildLeaveStatus(void); +void (*CatchChildLeaveStatus(void))(int); struct sockaddr; diff --git a/lib/util/signal.c b/lib/util/signal.c index ead947e..33a9900 100644 --- a/lib/util/signal.c +++ b/lib/util/signal.c @@ -129,16 +129,16 @@ void (*CatchSignal(int signum,void (*handler)(int )))(int) Ignore SIGCLD via whatever means is necessary for this OS. **/ -void CatchChild(void) +void (*CatchChild(void))(int) { - CatchSignal(SIGCLD, sig_cld); + return CatchSignal(SIGCLD, sig_cld); } /** Catch SIGCLD but leave the child around so it's status can be reaped. **/ -void CatchChildLeaveStatus(void) +void (*CatchChildLeaveStatus(void))(int) { - CatchSignal(SIGCLD, sig_cld_leave_status); + return CatchSignal(SIGCLD, sig_cld_leave_status); } -- 2.1.0.rc2.206.gedb03e5 From 0701805814cddfcb2c57a280d3488ab1a99cd26c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 23 Sep 2014 14:51:18 -0700 Subject: [PATCH 2/2] s3: lib: Signal handling - ensure smbrun and change password code save and restore existing SIGCHLD handlers. Bug #10831 - SIGCLD Signal handler not correctly reinstalled on old library code use - smbrun etc. https://bugzilla.samba.org/show_bug.cgi?id=10831 Signed-off-by: Jeremy Allison Reviewed-by: Martin Schwenke --- source3/lib/smbrun.c | 18 ++++++++++-------- source3/rpc_server/samr/srv_samr_chgpasswd.c | 9 +++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index 15a0c88..55f7a87 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -73,6 +73,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) pid_t pid; uid_t uid = current_user.ut.uid; gid_t gid = current_user.ut.gid; + void (*saved_handler)(int); /* * Lose any elevated privileges. @@ -94,11 +95,11 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) * SIGCLD signals as it also eats the exit status code. JRA. */ - CatchChildLeaveStatus(); + saved_handler = CatchChildLeaveStatus(); if ((pid=fork()) < 0) { DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) )); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); if (outfd) { close(*outfd); *outfd = -1; @@ -123,7 +124,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) break; } - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); if (wpid != pid) { DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno))); @@ -148,7 +149,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) return status; } - CatchChild(); + (void)CatchChild(); /* we are in the child. we exec /bin/sh to do the work for us. we don't directly exec the command we want because it may be a @@ -237,6 +238,7 @@ int smbrunsecret(const char *cmd, const char *secret) uid_t uid = current_user.ut.uid; gid_t gid = current_user.ut.gid; int ifd[2]; + void (*saved_handler)(int); /* * Lose any elevated privileges. @@ -257,11 +259,11 @@ int smbrunsecret(const char *cmd, const char *secret) * SIGCLD signals as it also eats the exit status code. JRA. */ - CatchChildLeaveStatus(); + saved_handler = CatchChildLeaveStatus(); if ((pid=fork()) < 0) { DEBUG(0, ("smbrunsecret: fork failed with error %s\n", strerror(errno))); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); return errno; } @@ -293,7 +295,7 @@ int smbrunsecret(const char *cmd, const char *secret) break; } - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); if (wpid != pid) { DEBUG(2, ("waitpid(%d) : %s\n", (int)pid, strerror(errno))); @@ -309,7 +311,7 @@ int smbrunsecret(const char *cmd, const char *secret) return status; } - CatchChild(); + (void)CatchChild(); /* we are in the child. we exec /bin/sh to do the work for us. we don't directly exec the command we want because it may be a diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c index 1c9c33a..684ccee 100644 --- a/source3/rpc_server/samr/srv_samr_chgpasswd.c +++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c @@ -391,6 +391,7 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass, pid_t pid, wpid; int wstat; bool chstat = False; + void (*saved_handler)(int); if (pass == NULL) { DEBUG(0, ("chat_with_program: user doesn't exist in the UNIX password database.\n")); @@ -408,13 +409,13 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass, * SIGCLD signals as it also eats the exit status code. JRA. */ - CatchChildLeaveStatus(); + saved_handler = CatchChildLeaveStatus(); if ((pid = fork()) < 0) { DEBUG(3, ("chat_with_program: Cannot fork() child for password change: %s\n", pass->pw_name)); SAFE_FREE(slavedev); close(master); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); return (False); } @@ -439,14 +440,14 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass, if (wpid < 0) { DEBUG(3, ("chat_with_program: The process is no longer waiting!\n\n")); close(master); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); return (False); } /* * Go back to ignoring children. */ - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); close(master); -- 2.1.0.rc2.206.gedb03e5