xorl %eax, %eax

CVE-2009-0587: Evolution Data Server Base64 Integer Overflows

leave a comment »

This vulnerability was reported by Tomas Hoger of Red Hat and it affects Evolution Data Server prior to 2.24.5 release. Here is the first buggy routine from addressbook/libebook/e-vcard.c file.

 *
 * Copyright (C) 2003 Ximian, Inc.
         ...
char *
_evc_base64_encode_simple (const char *data, size_t len)
{
    unsigned char *out;
    int state = 0, outlen;
    unsigned int save = 0;

    g_return_val_if_fail (data != NULL, NULL);

    out = g_malloc (len * 4 / 3 + 5);
    outlen = _evc_base64_encode_close ((unsigned char *)data, len, FALSE,
                      out, &state, &save);
    out[outlen] = '';
    return (char *)out;
}

The bug is really obvious, since length is derived from a user controlled string, the size calculation inside g_malloc() can easily lead to an integer overflow and therefore invalid allocation (by the way, there is no check if “out” is NULL that it might be if the allocation failed). To fix this, they changed that function by applying this patch:

     g_return_val_if_fail (data != NULL, NULL);

-    out = g_malloc (len * 4 / 3 + 5);
+    if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3)
+        return NULL;
+
+    out = g_malloc ((len / 3 + 1) * 4 + 1);
     outlen = _evc_base64_encode_close ((unsigned char *)data, len, FALSE,

This way it checks that “len” won’t overflow if that calculation is performed. A similar integer overflow was also present at camel/camel-mime-utils.c in the following routine:

/**
 * camel_base64_encode_simple:
 * @data: binary stream of data to encode
 * @len: length of data
 *
 * Base64 encodes a block of memory.
 *
 * Returns a string containing the base64 encoded data
 **/
char *
camel_base64_encode_simple (const char *data, size_t len)
{
    unsigned char *out;
    int state = 0, outlen;
    unsigned int save = 0;

    out = g_malloc (len * 4 / 3 + 5);
    outlen = camel_base64_encode_close ((unsigned char *)data, len, FALSE,
                      out, &state, &save);
    out[outlen] = '';
    return (char *)out;
}

Consequently, this was patched like this:


-    out = g_malloc (len * 4 / 3 + 5);
+    if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3)
+        g_error("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)",
+            G_STRLOC, len);
+
+    out = g_malloc ((len / 3 + 1) * 4 + 1);
     outlen = camel_base64_encode_close ((unsigned char *)data, len, FALSE,

Written by xorl

June 10, 2009 at 14:55

Posted in vulnerabilities

Leave a comment