summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authordengbo <dengbo@uniontech.com>2022-07-06 14:07:05 +0800
committerDmitry V. Levin <ldv@altlinux.org>2022-07-15 08:00:00 +0000
commitbd86ffffea356aba157cdc436f0537ac05da39e0 (patch)
tree97b162a0a94fa85d31cd9fab74d499cf0a966236 /modules
parent1180bde923a22605fe8075cd1fe7992ed7513411 (diff)
downloadlinux-pam-git-bd86ffffea356aba157cdc436f0537ac05da39e0.tar.gz
pam_exec: add SIGCHLD protection handle
* modules/pam_exec/pam_exec.c (call_exec): Save the SIGCHLD handler and reset it to the default before calling fork, restore the handler after waitpid returns. Resolves: https://github.com/linux-pam/linux-pam/issues/405
Diffstat (limited to 'modules')
-rw-r--r--modules/pam_exec/pam_exec.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c
index 23cc0bac..aeb98cdc 100644
--- a/modules/pam_exec/pam_exec.c
+++ b/modules/pam_exec/pam_exec.c
@@ -48,6 +48,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <signal.h>
#include <security/pam_modules.h>
#include <security/pam_modutil.h>
@@ -105,6 +106,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh,
FILE *stdout_file = NULL;
int retval;
const char *name;
+ struct sigaction newsa, oldsa;
if (argc < 1) {
pam_syslog (pamh, LOG_ERR,
@@ -226,6 +228,13 @@ call_exec (const char *pam_type, pam_handle_t *pamh,
return PAM_SERVICE_ERR;
}
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) {
+ pam_syslog(pamh, LOG_ERR, "failed to reset SIGCHLD handler: %m");
+ return PAM_SYSTEM_ERR;
+ }
+
pid = fork();
if (pid == -1)
return PAM_SYSTEM_ERR;
@@ -263,6 +272,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh,
while ((rc = waitpid (pid, &status, 0)) == -1 &&
errno == EINTR);
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
if (rc == (pid_t)-1)
{
pam_syslog (pamh, LOG_ERR, "waitpid returns with -1: %m");