diff options
author | Sam Hartman <hartmans@debian.org> | 2024-02-27 21:25:44 -0700 |
---|---|---|
committer | Sam Hartman <hartmans@debian.org> | 2024-02-27 21:25:44 -0700 |
commit | 58c5a173ca608476917893e9054cf3d53d0b0744 (patch) | |
tree | c5d2ab69a993c150f48f705bff9d76c1139f1e33 /modules/pam_exec/pam_exec.c | |
parent | 80d000dd6637be445a9a0fd930de765cc40352da (diff) | |
parent | 56cd5768b32fd97a7156977dcbbd40715e158e9c (diff) | |
download | pam-58c5a173ca608476917893e9054cf3d53d0b0744.tar.gz pam-58c5a173ca608476917893e9054cf3d53d0b0744.tar.bz2 pam-58c5a173ca608476917893e9054cf3d53d0b0744.zip |
Merge in 1.5.3 from experimental
Diffstat (limited to 'modules/pam_exec/pam_exec.c')
-rw-r--r-- | modules/pam_exec/pam_exec.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c index 05dec167..9d2145dc 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, @@ -182,6 +184,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, if (retval != PAM_SUCCESS) { + pam_overwrite_string (resp); _pam_drop (resp); if (retval == PAM_CONV_AGAIN) retval = PAM_INCOMPLETE; @@ -192,6 +195,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, { pam_set_item (pamh, PAM_AUTHTOK, resp); strncpy (authtok, resp, sizeof(authtok) - 1); + pam_overwrite_string (resp); _pam_drop (resp); } } @@ -200,6 +204,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, if (pipe(fds) != 0) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "Could not create pipe: %m"); return PAM_SYSTEM_ERR; } @@ -210,25 +215,38 @@ call_exec (const char *pam_type, pam_handle_t *pamh, { if (pipe(stdout_fds) != 0) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "Could not create pipe: %m"); return PAM_SYSTEM_ERR; } stdout_file = fdopen(stdout_fds[0], "r"); if (!stdout_file) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "Could not fdopen pipe: %m"); return PAM_SYSTEM_ERR; } } if (optargc >= argc) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "No path given as argument"); return PAM_SERVICE_ERR; } + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { + pam_overwrite_array(authtok); + pam_syslog(pamh, LOG_ERR, "failed to reset SIGCHLD handler: %m"); + return PAM_SYSTEM_ERR; + } + pid = fork(); - if (pid == -1) + if (pid == -1) { + pam_overwrite_array(authtok); return PAM_SYSTEM_ERR; + } if (pid > 0) /* parent */ { int status = 0; @@ -246,6 +264,8 @@ call_exec (const char *pam_type, pam_handle_t *pamh, close(fds[1]); } + pam_overwrite_array(authtok); + if (use_stdout) { char buf[4096]; @@ -263,6 +283,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"); @@ -305,9 +326,9 @@ call_exec (const char *pam_type, pam_handle_t *pamh, } else /* child */ { - char **arggv; + const char **arggv; int i; - char **envlist, **tmp; + char **envlist; int envlen, nitems; char *envstr; enum pam_modutil_redirect_fd redirect_stdin = @@ -315,6 +336,8 @@ call_exec (const char *pam_type, pam_handle_t *pamh, enum pam_modutil_redirect_fd redirect_stdout = (use_stdout || logfile) ? PAM_MODUTIL_IGNORE_FD : PAM_MODUTIL_NULL_FD; + pam_overwrite_array(authtok); + /* First, move all the pipes off of stdin, stdout, and stderr, to ensure * that calls to dup2 won't close them. */ @@ -418,7 +441,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, _exit (ENOMEM); for (i = 0; i < (argc - optargc); i++) - arggv[i] = strdup(argv[i+optargc]); + arggv[i] = argv[i+optargc]; arggv[i] = NULL; /* @@ -430,14 +453,12 @@ call_exec (const char *pam_type, pam_handle_t *pamh, /* nothing */ ; nitems = PAM_ARRAY_SIZE(env_items); /* + 2 because of PAM_TYPE and NULL entry */ - tmp = realloc(envlist, (envlen + nitems + 2) * sizeof(*envlist)); - if (tmp == NULL) + envlist = realloc(envlist, (envlen + nitems + 2) * sizeof(*envlist)); + if (envlist == NULL) { - free(envlist); pam_syslog (pamh, LOG_CRIT, "realloc environment failed: %m"); _exit (ENOMEM); } - envlist = tmp; for (i = 0; i < nitems; ++i) { const void *item; @@ -446,7 +467,6 @@ call_exec (const char *pam_type, pam_handle_t *pamh, continue; if (asprintf(&envstr, "%s=%s", env_items[i].name, (const char *)item) < 0) { - free(envlist); pam_syslog (pamh, LOG_CRIT, "prepare environment failed: %m"); _exit (ENOMEM); } @@ -456,7 +476,6 @@ call_exec (const char *pam_type, pam_handle_t *pamh, if (asprintf(&envstr, "PAM_TYPE=%s", pam_type) < 0) { - free(envlist); pam_syslog (pamh, LOG_CRIT, "prepare environment failed: %m"); _exit (ENOMEM); } @@ -466,10 +485,11 @@ call_exec (const char *pam_type, pam_handle_t *pamh, if (debug) pam_syslog (pamh, LOG_DEBUG, "Calling %s ...", arggv[0]); - execve (arggv[0], arggv, envlist); + DIAG_PUSH_IGNORE_CAST_QUAL; + execve (arggv[0], (char **) arggv, envlist); + DIAG_POP_IGNORE_CAST_QUAL; i = errno; pam_syslog (pamh, LOG_ERR, "execve(%s,...) failed: %m", arggv[0]); - free(envlist); _exit (i); } return PAM_SYSTEM_ERR; /* will never be reached. */ |