Make sure send_token.length is 4 bytes before reading the data.

Fix the buf_size type to be uint32_t instead of long.  ntohl()
operates on, and returns, a 32 bit unsigned integer.  Most
architectures now use a 64-bit long.

I believe this only worked because in Little-Endian, the
least-significant bits come first, so even though we were using 8
bytes of send_token.value (4 of which were out of bounds) for the cast
to long, only the first 4 bytes were used to truncate to the uint32_t
that ntohl() used.  Likewise when we converted htonl() further down.

Additionally, the comments indicate that mutt wasn't using buf_size in
any case, so perhaps that also explains the lack of bug reports.

Thanks to [email protected] for the security report.
---
This is 6 in the list evilrabbit sent.

 imap/auth_gss.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/imap/auth_gss.c b/imap/auth_gss.c
index 4fb6d7e1..fb9e50d8 100644
--- a/imap/auth_gss.c
+++ b/imap/auth_gss.c
@@ -108,7 +108,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const 
char* method)
   int cflags;
   OM_uint32 maj_stat, min_stat;
   BUFFER *buf1 = NULL, *buf2 = NULL;
-  unsigned long buf_size;
+  uint32_t buf_size;
   int rc, retval = IMAP_AUTH_FAILURE;
 
   if (!mutt_bit_isset (idata->capabilities, AGSSAPI))
@@ -259,6 +259,14 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const 
char* method)
   }
   dprint (2, (debugfile, "Credential exchange complete\n"));
 
+  if (send_token.length < 4)
+  {
+    /* TODO: convert to muttdbg() in master branch merge */
+    dprint(2, (debugfile, "Truncated security level data\n"));
+    gss_release_buffer(&min_stat, &send_token);
+    goto err_abort_cmd;
+  }
+
   /* first octet is security levels supported. We want NONE */
 #ifdef DEBUG
   server_conf_flags = ((char*) send_token.value)[0];
@@ -272,7 +280,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const 
char* method)
 
   /* we don't care about buffer size if we don't wrap content. But here it is 
*/
   ((char*) send_token.value)[0] = 0;
-  buf_size = ntohl (*((long *) send_token.value));
+  buf_size = ntohl(*((uint32_t *) send_token.value));
   gss_release_buffer (&min_stat, &send_token);
   dprint (2, (debugfile, "Unwrapped security level flags: %c%c%c\n",
               server_conf_flags & GSS_AUTH_P_NONE      ? 'N' : '-',
-- 
2.53.0

Reply via email to