From 1e056ee9171d44b85bfe2b09a6e78be78567d585 Mon Sep 17 00:00:00 2001
From: TJ Saunders <tj@castaglia.org>
Date: Thu, 30 Nov 2017 07:19:06 -0800
Subject: [PATCH] Issue #656: The keyboard-interative code in mod_sftp was
 changing the memory pool used for response, but not restoring the previous
 pool.

Newer compilers/distros are far better about catching this, with e.g. ASLR
and such; the previous behavior "worked" only because the memory areas in
question _usually_ were not trampled.  But with e.g. Ubuntu 17.10, such
trampling is noticed, caught, and rejected.
---
 contrib/mod_sftp/kbdint.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/contrib/mod_sftp/kbdint.c b/contrib/mod_sftp/kbdint.c
index 2a925c12b..6900f4dfc 100644
--- a/contrib/mod_sftp/kbdint.c
+++ b/contrib/mod_sftp/kbdint.c
@@ -1,6 +1,6 @@
 /*
  * ProFTPD - mod_sftp keyboard-interactive driver mgmt
- * Copyright (c) 2008-2016 TJ Saunders
+ * Copyright (c) 2008-2017 TJ Saunders
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -264,6 +264,7 @@ int sftp_kbdint_recv_response(pool *p, uint32_t expected_count,
   struct ssh2_packet *pkt;
   char mesg_type;
   int res;
+  pool *resp_pool = NULL;
 
   if (p == NULL ||
       rcvd_count == NULL ||
@@ -282,6 +283,9 @@ int sftp_kbdint_recv_response(pool *p, uint32_t expected_count,
 
   pr_response_clear(&resp_list);
   pr_response_clear(&resp_err_list);
+
+  /* Cache a reference to the current response pool used. */
+  resp_pool = pr_response_get_pool();
   pr_response_set_pool(pkt->pool);
 
   mesg_type = sftp_ssh2_packet_get_mesg_type(pkt);
@@ -290,6 +294,7 @@ int sftp_kbdint_recv_response(pool *p, uint32_t expected_count,
       "expecting USER_AUTH_INFO_RESP message, received %s (%d)",
       sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type);
     destroy_pool(pkt->pool);
+    pr_response_set_pool(resp_pool);
     errno = EPERM;
     return -1;
   }
@@ -315,6 +320,7 @@ int sftp_kbdint_recv_response(pool *p, uint32_t expected_count,
       expected_count != 1 ? "challenges" : "challenge",
       (unsigned long) resp_count, resp_count != 1 ? "responses" : "response");
     destroy_pool(pkt->pool);
+    pr_response_set_pool(resp_pool);
     errno = EPERM;
     return -1;
   }
@@ -324,6 +330,7 @@ int sftp_kbdint_recv_response(pool *p, uint32_t expected_count,
       "received too many responses (%lu > max %lu), rejecting",
       (unsigned long) resp_count, (unsigned long) SFTP_KBDINT_MAX_RESPONSES);
     destroy_pool(pkt->pool);
+    pr_response_set_pool(resp_pool);
     errno = EPERM;
     return -1;
   }
@@ -339,6 +346,7 @@ int sftp_kbdint_recv_response(pool *p, uint32_t expected_count,
   *rcvd_count = resp_count;
   *responses = ((const char **) list->elts);
   destroy_pool(pkt->pool);
+  pr_response_set_pool(resp_pool);
 
   return 0;
 }
