diff options
Diffstat (limited to 'modules/pam_xauth/pam_xauth.c')
-rw-r--r-- | modules/pam_xauth/pam_xauth.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c index ae731211..f3e2a40d 100644 --- a/modules/pam_xauth/pam_xauth.c +++ b/modules/pam_xauth/pam_xauth.c @@ -52,6 +52,7 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> +#include <signal.h> #include <security/pam_modules.h> #include <security/_pam_macros.h> @@ -99,6 +100,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, char *buffer = NULL; size_t buffer_size = 0; va_list ap; + struct sigaction newsa, oldsa; *output = NULL; @@ -114,6 +116,17 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, return -1; } + 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"); + close(ipipe[0]); + close(ipipe[1]); + close(opipe[0]); + close(opipe[1]); + return -1; + } + /* Fork off a child. */ child = fork(); if (child == -1) { @@ -128,7 +141,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, if (child == 0) { /* We're the child. */ size_t j; - const char *args[10]; + const char *args[10] = {}; /* Drop privileges. */ if (setgid(gid) == -1) { @@ -168,8 +181,6 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, PAM_MODUTIL_NULL_FD) < 0) { _exit(1); } - /* Initialize the argument list. */ - memset(args, 0, sizeof(args)); /* Convert the varargs list into a regular array of strings. */ va_start(ap, command); args[0] = command; @@ -209,6 +220,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, } close(opipe[0]); waitpid(child, NULL, 0); + sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ return -1; } /* Save the new buffer location, copy the newly-read data into @@ -225,6 +237,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, close(opipe[0]); *output = buffer; waitpid(child, NULL, 0); + sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ return 0; } @@ -532,7 +545,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, xauth, "-f", cookiefile, "nlist", display, NULL) == 0) { #ifdef WITH_SELINUX - security_context_t context = NULL; + char *context_raw = NULL; #endif PAM_MODUTIL_DEF_PRIVS(privs); @@ -549,9 +562,8 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, } /* Allocate enough space to hold an adjusted name. */ tlen = strlen(display) + LINE_MAX + 1; - t = malloc(tlen); + t = calloc(1, tlen); if (t != NULL) { - memset(t, 0, tlen); if (gethostname(t, tlen - 1) != -1) { /* Append the protocol and then the * screen number. */ @@ -626,16 +638,16 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, if (is_selinux_enabled() > 0) { struct selabel_handle *ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0); if (ctx != NULL) { - if (selabel_lookup(ctx, &context, - xauthority + sizeof(XAUTHENV), S_IFREG) != 0) { + if (selabel_lookup_raw(ctx, &context_raw, + xauthority + sizeof(XAUTHENV), S_IFREG) != 0) { pam_syslog(pamh, LOG_WARNING, "could not get SELinux label for '%s'", xauthority + sizeof(XAUTHENV)); } selabel_close(ctx); - if (setfscreatecon(context)) { + if (setfscreatecon_raw(context_raw)) { pam_syslog(pamh, LOG_WARNING, - "setfscreatecon(%s) failed: %m", context); + "setfscreatecon_raw(%s) failed: %m", context_raw); } } } @@ -646,9 +658,9 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, "error creating temporary file `%s': %m", xauthority + sizeof(XAUTHENV)); #ifdef WITH_SELINUX - if (context != NULL) { - free(context); - setfscreatecon(NULL); + if (context_raw != NULL) { + free(context_raw); + setfscreatecon_raw(NULL); } #endif /* WITH_SELINUX */ if (fd >= 0) |