PAM: fix crash in the pam expansion condition. Bug 2489
authorFabian Groffen <grobian@gentoo.org>
Tue, 10 Dec 2019 17:32:12 +0000 (17:32 +0000)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Wed, 11 Dec 2019 16:27:18 +0000 (17:27 +0100)
Broken-by: f3ebb786e4
(cherry picked from commit dcbfbadac2f557dc73bbcf2b26aadf50f8414ca1)

doc/doc-txt/ChangeLog
src/src/auths/call_pam.c

index 1e8a2d216ea4a3d9d1c2c476d4fd944bfcdcc5ce..a71cb9f0f95f30f83dfe62673e6e6cb555e4bdbd 100644 (file)
@@ -3,6 +3,17 @@ affect Exim's operation, with an unchanged configuration file.  For new
 options, and new features, see the NewStuff file next to this ChangeLog.
 
 
+Exim version 4.93+fixes
+-----------------------
+This is not an official release. It is just a branch, collecting
+proposed bugfixes. Depending on your environment the fixes may be
+necessary to build and/or run Exim successfully.
+
+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
 -----------------
 
index 9a46b6b63c45c2156cb5c6b2df0ba5738d652a4e..c96e146d15fae7bf6f3e3391d62b7d88dec312cc 100644 (file)
@@ -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;
     }
   }