From c66ad27cc8bab238d71dc3e1fca15c6a2665d49d Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Mon, 30 Nov 2020 06:06:28 +0000 Subject: [PATCH] base64: only allow padding bytes at the end of a string when decoding --- base64.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/base64.c b/base64.c index da28e614..c0dfc807 100644 --- a/base64.c +++ b/base64.c @@ -12,8 +12,8 @@ #include "log.h" enum { - P = 0, // Padding byte (=) - I = 128, // Invalid byte ([^A-Za-z0-9+/=]) + P = 1 << 6, // Padding byte (=) + I = 1 << 7, // Invalid byte ([^A-Za-z0-9+/=]) }; static const uint8_t reverse_lookup[256] = { @@ -63,10 +63,16 @@ base64_decode(const char *s) unsigned c = reverse_lookup[(unsigned char)s[i + 2]]; unsigned d = reverse_lookup[(unsigned char)s[i + 3]]; - if (unlikely((a | b | c | d) & I)) { - free(ret); - errno = EINVAL; - return NULL; + unsigned u = a | b | c | d; + if (unlikely(u & I)) + goto invalid; + + if (unlikely(u & P)) { + if (unlikely(i + 4 != len || (a | b) & P || (c & P && !(d & P)))) + goto invalid; + + c &= 63; + d &= 63; } uint32_t v = a << 18 | b << 12 | c << 6 | d << 0; @@ -82,6 +88,11 @@ base64_decode(const char *s) ret[len / 4 * 3] = '\0'; return ret; + +invalid: + free(ret); + errno = EINVAL; + return NULL; } char *