Module Name: src Committed By: christos Date: Thu Jun 20 20:54:02 UTC 2013
Modified Files: src/usr.bin/su: su_pam.c Log Message: - don't re-use the va list twice, leads to coredumps. - introduce and use a "safe" version of pam_strerror(3) that does not return NULL To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/usr.bin/su/su_pam.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/su/su_pam.c diff -u src/usr.bin/su/su_pam.c:1.17 src/usr.bin/su/su_pam.c:1.18 --- src/usr.bin/su/su_pam.c:1.17 Wed Mar 14 22:02:23 2012 +++ src/usr.bin/su/su_pam.c Thu Jun 20 16:54:02 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: su_pam.c,v 1.17 2012/03/15 02:02:23 joerg Exp $ */ +/* $NetBSD: su_pam.c,v 1.18 2013/06/20 20:54:02 christos Exp $ */ /* * Copyright (c) 1988 The Regents of the University of California. @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988\ #if 0 static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";*/ #else -__RCSID("$NetBSD: su_pam.c,v 1.17 2012/03/15 02:02:23 joerg Exp $"); +__RCSID("$NetBSD: su_pam.c,v 1.18 2013/06/20 20:54:02 christos Exp $"); #endif #endif /* not lint */ @@ -83,6 +83,18 @@ static const struct pam_conv pamc = { &o static void logit(const char *, ...) __printflike(1, 2); +static const char * +safe_pam_strerror(pam_handle_t *pamh, int pam_err) { + const char *msg; + + if ((msg = pam_strerror(pamh, pam_err)) != NULL) + return msg; + + static char buf[1024]; + snprintf(buf, sizeof(buf), "Unknown pam error %d", pam_err); + return buf; +} + int main(int argc, char **argv) { @@ -215,7 +227,7 @@ main(int argc, char **argv) PAM_END("pam_start"); /* Things went really bad... */ syslog(LOG_ERR, "pam_start failed: %s", - pam_strerror(pamh, pam_err)); + safe_pam_strerror(pamh, pam_err)); errx(EXIT_FAILURE, "pam_start failed"); } @@ -239,9 +251,9 @@ main(int argc, char **argv) */ if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS) { syslog(LOG_WARNING, "BAD SU %s to %s%s: %s", - username, user, ontty(), pam_strerror(pamh, pam_err)); + username, user, ontty(), safe_pam_strerror(pamh, pam_err)); (void)pam_end(pamh, pam_err); - errx(EXIT_FAILURE, "Sorry: %s", pam_strerror(pamh, pam_err)); + errx(EXIT_FAILURE, "Sorry: %s", safe_pam_strerror(pamh, pam_err)); } /* @@ -267,7 +279,7 @@ main(int argc, char **argv) pam_err = pam_get_item(pamh, PAM_USER, &newuser); if (pam_err != PAM_SUCCESS) { syslog(LOG_WARNING, - "pam_get_item(PAM_USER): %s", pam_strerror(pamh, pam_err)); + "pam_get_item(PAM_USER): %s", safe_pam_strerror(pamh, pam_err)); } else { user = (char *)__UNCONST(newuser); if (getpwnam_r(user, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0 || @@ -423,11 +435,11 @@ out: pam_err = pam_setcred(pamh, PAM_DELETE_CRED); if (pam_err != PAM_SUCCESS) logit("pam_setcred: %s", - pam_strerror(pamh, pam_err)); + safe_pam_strerror(pamh, pam_err)); pam_err = pam_close_session(pamh, 0); if (pam_err != PAM_SUCCESS) logit("pam_close_session: %s", - pam_strerror(pamh, pam_err)); + safe_pam_strerror(pamh, pam_err)); (void)pam_end(pamh, pam_err); exit(WEXITSTATUS(status)); break; @@ -543,7 +555,7 @@ out: (void)execv(shell, np); err(EXIT_FAILURE, "%s", shell); done: - logit("%s: %s", func, pam_strerror(pamh, pam_err)); + logit("%s: %s", func, safe_pam_strerror(pamh, pam_err)); (void)pam_end(pamh, pam_err); return EXIT_FAILURE; } @@ -555,6 +567,8 @@ logit(const char *fmt, ...) va_start(ap, fmt); vwarnx(fmt, ap); + va_end(ap); + va_start(ap, fmt); vsyslog(LOG_ERR, fmt, ap); va_end(ap); }