From dcbfbadac2f557dc73bbcf2b26aadf50f8414ca1 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Tue, 10 Dec 2019 17:32:12 +0000 Subject: [PATCH 1/1] PAM: fix crash in the pam expansion condition. Bug 2489 Broken-by: f3ebb786e4 --- doc/doc-txt/ChangeLog | 4 ++++ src/src/auths/call_pam.c | 35 +++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 9f8775f0f..6a06e440f 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -24,6 +24,10 @@ JH/05 Regard command-line receipients as tainted. JH/06 Bug 340: Remove the daemon pid file on exit, whe due to SIGTERM. +JH/07 Bug 2489: Fix crash in the "pam" expansion condition. It seems that the + PAM library frees one of the arguments given to it, despite the + documentation. Therefore a plain malloc must be used. + Exim version 4.93 ----------------- diff --git a/src/src/auths/call_pam.c b/src/src/auths/call_pam.c index 9a46b6b63..c96e146d1 100644 --- a/src/src/auths/call_pam.c +++ b/src/src/auths/call_pam.c @@ -69,9 +69,11 @@ pam_converse (int num_msg, PAM_CONVERSE_ARG2_TYPE **msg, int sep = 0; struct pam_response *reply; -if (pam_arg_ended) return PAM_CONV_ERR; +/* It seems that PAM frees reply[] */ -reply = store_get(sizeof(struct pam_response) * num_msg, FALSE); +if ( pam_arg_ended + || !(reply = malloc(sizeof(struct pam_response) * num_msg))) + return PAM_CONV_ERR; for (int i = 0; i < num_msg; i++) { @@ -80,25 +82,26 @@ for (int i = 0; i < num_msg; i++) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: - arg = string_nextinlist(&pam_args, &sep, big_buffer, big_buffer_size); - if (arg == NULL) - { - arg = US""; - pam_arg_ended = TRUE; - } - reply[i].resp = CS string_copy_perm(arg, FALSE); /* PAM frees resp */ - reply[i].resp_retcode = PAM_SUCCESS; - break; + arg = string_nextinlist(&pam_args, &sep, big_buffer, big_buffer_size); + if (!arg) + { + arg = US""; + pam_arg_ended = TRUE; + } + reply[i].resp = CS string_copy_malloc(arg); /* PAM frees resp */ + reply[i].resp_retcode = PAM_SUCCESS; + break; case PAM_TEXT_INFO: /* Just acknowledge messages */ case PAM_ERROR_MSG: - reply[i].resp_retcode = PAM_SUCCESS; - reply[i].resp = NULL; - break; + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = NULL; + break; default: /* Must be an error of some sort... */ - pam_conv_had_error = TRUE; - return PAM_CONV_ERR; + free(reply); + pam_conv_had_error = TRUE; + return PAM_CONV_ERR; } } -- 2.25.1