]> granicus.if.org Git - curl/commitdiff
Fix for a base64 decode heap buffer overflow vulnerability.
authorDan Fandrich <dan@coneharvesters.com>
Mon, 28 Feb 2005 23:54:17 +0000 (23:54 +0000)
committerDan Fandrich <dan@coneharvesters.com>
Mon, 28 Feb 2005 23:54:17 +0000 (23:54 +0000)
lib/base64.c

index 54e4ed5d79f586646da8b85c12049cc18c3fe26a..98b2813090662e88d668aefc4cefcef6e38796b7 100644 (file)
@@ -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];