Don't read past the end of a tag when converting from UTF-16
authorDan Fandrich <dan@coneharvesters.com>
Thu, 12 Jul 2012 17:12:24 +0000 (10:12 -0700)
committerDan Fandrich <dan@coneharvesters.com>
Thu, 12 Jul 2012 17:12:24 +0000 (10:12 -0700)
This fixes CVE-2012-2813

libexif/exif-entry.c

index becf1f1..c69891d 100644 (file)
@@ -1346,10 +1346,23 @@ exif_entry_get_value (ExifEntry *e, char *val, unsigned int maxlen)
        case EXIF_TAG_XP_AUTHOR:
        case EXIF_TAG_XP_KEYWORDS:
        case EXIF_TAG_XP_SUBJECT:
+       {
+               /* Sanity check the size to prevent overflow */
+               if (e->size+sizeof(unsigned short) < e->size) break;
+
+               /* The tag may not be U+0000-terminated , so make a local
+                  U+0000-terminated copy before converting it */
+               unsigned short *utf16 = exif_mem_alloc (e->priv->mem, e->size+sizeof(unsigned short));
+               if (!utf16) break;
+               memcpy(utf16, e->data, e->size);
+               utf16[e->size/sizeof(unsigned short)] = 0;
+
                /* Warning! The texts are converted from UTF16 to UTF8 */
                /* FIXME: use iconv to convert into the locale encoding */
-               exif_convert_utf16_to_utf8(val, (unsigned short*)e->data, MIN(maxlen, e->size));
+               exif_convert_utf16_to_utf8(val, utf16, maxlen);
+               exif_mem_free(e->priv->mem, utf16);
                break;
+       }
 
        default:
                /* Use a generic value formatting */