From 2975c2abf398e7c300ad444648a9c136c4dd8c2b Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Sat, 28 Sep 2024 14:16:53 +0000 Subject: [PATCH] Shut down forked PAM handle Shutting down the forked PAM handle must be done as per the Linux-PAM documentation, specifically after setuid. This is not a new requirement, but until recently (~2021) there was no consequence to not doing so. `pam_cap` now requires the handle to be shut down correctly in order to configure ambient capabilities for the session. Importantly, these must be configured after setuid, as setuid clears the ambient capability vector. Signed-off-by: Tudor Brindus --- auth-pam.c | 12 ++++++++++++ auth-pam.h | 1 + session.c | 21 +++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/auth-pam.c b/auth-pam.c index 13c0a792e99e..8f0d6ce2cad5 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -661,6 +661,18 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg, static struct pam_conv store_conv = { sshpam_store_conv, NULL }; +void +sshpam_cleanup_in_child(void) +{ + if (sshpam_handle == NULL) + return; + +#ifdef PAM_DATA_SILENT + /* macOS PAM doesn't support PAM_DATA_SILENT. */ + pam_end(sshpam_handle, PAM_SUCCESS | PAM_DATA_SILENT); +#endif +} + void sshpam_cleanup(void) { diff --git a/auth-pam.h b/auth-pam.h index 8d801c689aa6..ba71544d8424 100644 --- a/auth-pam.h +++ b/auth-pam.h @@ -39,6 +39,7 @@ char ** fetch_pam_child_environment(void); void free_pam_environment(char **); void sshpam_thread_cleanup(void); void sshpam_cleanup(void); +void sshpam_cleanup_in_child(void); int sshpam_auth_passwd(Authctxt *, const char *); int sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); diff --git a/session.c b/session.c index c9415114db94..19d17f58f4cf 100644 --- a/session.c +++ b/session.c @@ -1545,10 +1545,23 @@ do_child(struct ssh *ssh, Session *s, const char *command) #endif /* HAVE_OSF_SIA */ #ifdef USE_PAM - if (options.use_pam && !is_pam_session_open()) { - debug3("PAM session not opened, exiting"); - display_loginmsg(); - exit(254); + if (options.use_pam) { + if (!is_pam_session_open()) { + debug3("PAM session not opened, exiting"); + display_loginmsg(); + exit(254); + } + + /* + * Shutting down the forked PAM handle must be done as per the + * Linux-PAM documentation, specifically after setuid. + * + * Concretely, this ensures pam_cap can configure ambient + * capabilities for the session by applying them during + * cleanup. Without this, the ambient capability vector gets + * cleared during setuid. + */ + sshpam_cleanup_in_child(); } #endif