Commit 3d9028fe authored by Kevin J. McCarthy's avatar Kevin J. McCarthy

Check outbuf length in mutt_from_base64()

The obuf can be overflowed in auth_cram.c, and possibly auth_gss.c.

Thanks to Jeriko One for the bug report.
parent 6962328c
...@@ -81,7 +81,7 @@ void mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len, ...@@ -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. /* Convert '\0'-terminated base 64 string to raw bytes.
* Returns length of returned buffer, or -1 on error */ * 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; int len = 0;
register unsigned char digit1, digit2, digit3, digit4; register unsigned char digit1, digit2, digit3, digit4;
...@@ -103,14 +103,20 @@ int mutt_from_base64 (char *out, const char *in) ...@@ -103,14 +103,20 @@ int mutt_from_base64 (char *out, const char *in)
in += 4; in += 4;
/* digits are already sanity-checked */ /* digits are already sanity-checked */
if (len == olen)
return len;
*out++ = (base64val(digit1) << 2) | (base64val(digit2) >> 4); *out++ = (base64val(digit1) << 2) | (base64val(digit2) >> 4);
len++; len++;
if (digit3 != '=') if (digit3 != '=')
{ {
if (len == olen)
return len;
*out++ = ((base64val(digit2) << 4) & 0xf0) | (base64val(digit3) >> 2); *out++ = ((base64val(digit2) << 4) & 0xf0) | (base64val(digit3) >> 2);
len++; len++;
if (digit4 != '=') if (digit4 != '=')
{ {
if (len == olen)
return len;
*out++ = ((base64val(digit3) << 6) & 0xc0) | base64val(digit4); *out++ = ((base64val(digit3) << 6) & 0xc0) | base64val(digit4);
len++; len++;
} }
......
...@@ -71,7 +71,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata, const char* method) ...@@ -71,7 +71,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata, const char* method)
goto bail; 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")); dprint (1, (debugfile, "Error decoding base64 response.\n"));
goto bail; goto bail;
......
...@@ -197,7 +197,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) ...@@ -197,7 +197,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method)
goto bail; 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; request_buf.value = buf2;
sec_token = &request_buf; sec_token = &request_buf;
...@@ -233,7 +233,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) ...@@ -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")); dprint (1, (debugfile, "Error receiving server response.\n"));
goto bail; 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; request_buf.value = buf2;
maj_stat = gss_unwrap (&min_stat, context, &request_buf, &send_token, maj_stat = gss_unwrap (&min_stat, context, &request_buf, &send_token,
......
...@@ -397,7 +397,7 @@ ADDRESS *alias_reverse_lookup (ADDRESS *); ...@@ -397,7 +397,7 @@ ADDRESS *alias_reverse_lookup (ADDRESS *);
/* base64.c */ /* base64.c */
void mutt_to_base64 (unsigned char*, const unsigned char*, size_t, size_t); 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 */ /* utf8.c */
int mutt_wctoutf8 (char *s, unsigned int c, size_t buflen); int mutt_wctoutf8 (char *s, unsigned int c, size_t buflen);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment