diff options
author | Dan Fandrich <dan@coneharvesters.com> | 2005-02-28 23:54:17 +0000 |
---|---|---|
committer | Dan Fandrich <dan@coneharvesters.com> | 2005-02-28 23:54:17 +0000 |
commit | 0ddab51ad874b64e38e26840a916fc13f4d2ed7b (patch) | |
tree | ab130c6bf6abd511b0a5b79b0c7e85433753599c /lib/base64.c | |
parent | 9798432f567f1589f1da6216e2795ab10b733128 (diff) | |
download | curl-0ddab51ad874b64e38e26840a916fc13f4d2ed7b.tar.gz |
Fix for a base64 decode heap buffer overflow vulnerability.
Diffstat (limited to 'lib/base64.c')
-rw-r--r-- | lib/base64.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/base64.c b/lib/base64.c index 54e4ed5d7..98b281309 100644 --- a/lib/base64.c +++ b/lib/base64.c @@ -93,24 +93,38 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr) while((src[length] != '=') && src[length]) length++; - while(src[length+equalsTerm] == '=') + /* A maximum of two = padding characters is allowed */ + if(src[length] == '=') { equalsTerm++; - + if(src[length+equalsTerm] == '=') + equalsTerm++; + } numQuantums = (length + equalsTerm) / 4; + /* Don't allocate a buffer if the decoded length is 0 */ + if (numQuantums <= 0) + return 0; + rawlen = (numQuantums * 3) - equalsTerm; - newstr = malloc(rawlen+1); + /* The buffer must be large enough to make room for the last quantum + (which may be partially thrown out) and the zero terminator. */ + newstr = malloc(rawlen+4); if(!newstr) return 0; *outptr = newstr; + /* Decode all but the last quantum (which may not decode to a + multiple of 3 bytes) */ for(i = 0; i < numQuantums - 1; i++) { decodeQuantum((unsigned char *)newstr, src); newstr += 3; src += 4; } + /* This final decode may actually read slightly past the end of the buffer + if the input string is missing pad bytes. This will almost always be + harmless. */ decodeQuantum(lastQuantum, src); for(i = 0; i < 3 - equalsTerm; i++) newstr[i] = lastQuantum[i]; |