From: Tobias Stoeckmann Date: Fri, 3 Apr 2026 07:40:24 +0000 (+0200) Subject: su: Clean up PAM resources on all error paths X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff376bb595e803b7444de4dcfb6b4f4f4409ca38;p=thirdparty%2Futil-linux.git su: Clean up PAM resources on all error paths In most cases, PAM resources are already cleaned up in error paths. Some exceptions exist though. Signed-off-by: Tobias Stoeckmann --- diff --git a/login-utils/login.c b/login-utils/login.c index b6d8aaf2a..0f303e753 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -1094,8 +1094,8 @@ static void loginpam_session(struct login_context *cxt) rc = pam_setcred(pamh, PAM_REINITIALIZE_CRED); if (is_pam_failure(rc)) { - pam_setcred(cxt->pamh, PAM_DELETE_CRED); pam_close_session(pamh, 0); + pam_setcred(cxt->pamh, PAM_DELETE_CRED); loginpam_err(pamh, rc); } } diff --git a/login-utils/su-common.c b/login-utils/su-common.c index eb366678a..57651ea9e 100644 --- a/login-utils/su-common.c +++ b/login-utils/su-common.c @@ -407,8 +407,10 @@ static void supam_authenticate(struct su_context *su) * This is the only difference between runuser(1) and su(1). The command * runuser(1) does not required authentication, because user is root. */ - if (su->restricted) + if (su->restricted) { + pam_end(su->pamh, PAM_ABORT); errx(EXIT_FAILURE, _("may not be used by non-root users")); + } return; } @@ -554,10 +556,14 @@ static void create_watching_parent(struct su_context *su) ul_pty_slave_echo(su->pty, 1); /* create pty */ - if (ul_pty_setup(su->pty)) + if (ul_pty_setup(su->pty)) { + supam_cleanup(su, PAM_ABORT); err(EXIT_FAILURE, _("failed to create pseudo-terminal")); - if (ul_pty_signals_setup(su->pty)) + } + if (ul_pty_signals_setup(su->pty)) { + supam_cleanup(su, PAM_ABORT); err(EXIT_FAILURE, _("failed to initialize signals handler")); + } } #endif fflush(stdout); /* ??? */ @@ -760,9 +766,12 @@ static void init_groups(struct su_context *su, gid_t *groups, size_t ngroups) endgrent(); rc = pam_setcred(su->pamh, PAM_ESTABLISH_CRED); - if (is_pam_failure(rc)) - errx(EXIT_FAILURE, _("failed to establish user credentials: %s"), - pam_strerror(su->pamh, rc)); + if (is_pam_failure(rc)) { + const char *msg = pam_strerror(su->pamh, rc); + + supam_cleanup(su, rc); + errx(EXIT_FAILURE, _("failed to establish user credentials: %s"), msg); + } su->pam_has_cred = 1; } @@ -1216,8 +1225,10 @@ int su_main(int argc, char **argv, int mode) ON_DBG(PTY, ul_pty_init_debug(0xffff)); su->pty = ul_new_pty(su->isterm); - if (!su->pty) + if (!su->pty) { + supam_cleanup(su, PAM_ABORT); err(EXIT_FAILURE, _("failed to allocate pty handler")); + } } #endif create_watching_parent(su);