]> granicus.if.org Git - mutt/commitdiff
Check outbuf length in mutt_from_base64()
authorKevin McCarthy <kevin@8t8.us>
Fri, 13 Jul 2018 21:25:28 +0000 (14:25 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sun, 15 Jul 2018 15:21:44 +0000 (08:21 -0700)
The obuf can be overflowed in auth_cram.c, and possibly auth_gss.c.

Thanks to Jeriko One for the bug report.

base64.c
imap/auth_cram.c
imap/auth_gss.c
protos.h

index fd3ffb88aae31f41b8033435967d7ac7b4ad58f6..120d4baa8ecb2b93e6593da41315e8a016af9406 100644 (file)
--- a/base64.c
+++ b/base64.c
@@ -81,7 +81,7 @@ void mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len,
 
 /* Convert '\0'-terminated base 64 string to raw bytes.
  * Returns length of returned buffer, or -1 on error */
-int mutt_from_base64 (char *out, const char *in)
+int mutt_from_base64 (char *out, const char *in, size_t olen)
 {
   int len = 0;
   register unsigned char digit1, digit2, digit3, digit4;
@@ -103,14 +103,20 @@ int mutt_from_base64 (char *out, const char *in)
     in += 4;
 
     /* digits are already sanity-checked */
+    if (len == olen)
+      return len;
     *out++ = (base64val(digit1) << 2) | (base64val(digit2) >> 4);
     len++;
     if (digit3 != '=')
     {
+      if (len == olen)
+        return len;
       *out++ = ((base64val(digit2) << 4) & 0xf0) | (base64val(digit3) >> 2);
       len++;
       if (digit4 != '=')
       {
+        if (len == olen)
+          return len;
        *out++ = ((base64val(digit3) << 6) & 0xc0) | base64val(digit4);
        len++;
       }
index 9b6db9af61e838b7f3ae68c0048334708d58163a..876172156d8ad33f43e43bfee9a6c2cbe06fec9b 100644 (file)
@@ -71,7 +71,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata, const char* method)
     goto bail;
   }
 
-  if ((len = mutt_from_base64 (obuf, idata->buf + 2)) == -1)
+  if ((len = mutt_from_base64 (obuf, idata->buf + 2, sizeof(obuf) - 1)) == -1)
   {
     dprint (1, (debugfile, "Error decoding base64 response.\n"));
     goto bail;
index a08e7c2056a1f9793b5d5947185d2e309d52ff4e..e14f4aac6fcb00913dba68497578c45ca6fb9941 100644 (file)
@@ -197,7 +197,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method)
       goto bail;
     }
 
-    request_buf.length = mutt_from_base64 (buf2, idata->buf + 2);
+    request_buf.length = mutt_from_base64 (buf2, idata->buf + 2, sizeof(buf2));
     request_buf.value = buf2;
     sec_token = &request_buf;
 
@@ -233,7 +233,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method)
     dprint (1, (debugfile, "Error receiving server response.\n"));
     goto bail;
   }
-  request_buf.length = mutt_from_base64 (buf2, idata->buf + 2);
+  request_buf.length = mutt_from_base64 (buf2, idata->buf + 2, sizeof(buf2));
   request_buf.value = buf2;
 
   maj_stat = gss_unwrap (&min_stat, context, &request_buf, &send_token,
index 8bcda67fb0b64999d601ce4de8d9c82fcf77b631..f933e92551a73c0a25878e3cb40a42e19127c5f3 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -397,7 +397,7 @@ ADDRESS *alias_reverse_lookup (ADDRESS *);
 
 /* base64.c */
 void mutt_to_base64 (unsigned char*, const unsigned char*, size_t, size_t);
-int mutt_from_base64 (char*, const char*);
+int mutt_from_base64 (char*, const char*, size_t);
 
 /* utf8.c */
 int mutt_wctoutf8 (char *s, unsigned int c, size_t buflen);