From: Yue Tao <yue....@windriver.com>

[ CQID: WIND00366788 ]

The exif_data_load_data function in exif-data.c in the EXIF Tag
Parsing Library (aka libexif) before 0.6.21 allows remote attackers
to cause a denial of service (out-of-bounds read) or possibly
obtain sensitive information from process memory via crafted EXIF
tags in an image.

Signed-off-by: Yue Tao <yue....@windriver.com>
Signed-off-by: Robert Yang <liezhi.y...@windriver.com>
Signed-off-by: Mark Hatle <mark.ha...@windriver.com>
---
 .../libexif/0004-libexif-CVE-2012-2836.patch       | 140 +++++++++++++++++++++
 meta/recipes-support/libexif/libexif_0.6.20.bb     |   3 +-
 2 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 
meta/recipes-support/libexif/libexif/0004-libexif-CVE-2012-2836.patch

diff --git 
a/meta/recipes-support/libexif/libexif/0004-libexif-CVE-2012-2836.patch 
b/meta/recipes-support/libexif/libexif/0004-libexif-CVE-2012-2836.patch
new file mode 100644
index 0000000..430e35c
--- /dev/null
+++ b/meta/recipes-support/libexif/libexif/0004-libexif-CVE-2012-2836.patch
@@ -0,0 +1,140 @@
+Index: libexif/exif-data.c
+===================================================================
+RCS file: /cvsroot/libexif/libexif/libexif/exif-data.c,v
+retrieving revision 1.129
+retrieving revision 1.131
+diff -c -u -r1.129 -r1.131
+--- a/libexif/exif-data.c      8 Oct 2010 06:50:19 -0000       1.129
++++ b/libexif/exif-data.c      12 Jul 2012 17:28:26 -0000      1.131
+@@ -781,15 +781,15 @@
+ 
+ void
+ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
+-                   unsigned int ds_orig)
++                   unsigned int ds)
+ {
+       unsigned int l;
+       ExifLong offset;
+       ExifShort n;
+       const unsigned char *d = d_orig;
+-      unsigned int ds = ds_orig, len;
++      unsigned int len, fullds;
+ 
+-      if (!data || !data->priv || !d || !ds) 
++      if (!data || !data->priv || !d || !ds)
+               return;
+ 
+       exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
+@@ -807,21 +807,21 @@
+               exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
+                         "Found EXIF header.");
+       } else {
+-              while (1) {
+-                      while ((d[0] == 0xff) && ds) {
++              while (ds >= 3) {
++                      while (ds && (d[0] == 0xff)) {
+                               d++;
+                               ds--;
+                       }
+ 
+                       /* JPEG_MARKER_SOI */
+-                      if (d[0] == JPEG_MARKER_SOI) {
++                      if (ds && d[0] == JPEG_MARKER_SOI) {
+                               d++;
+                               ds--;
+                               continue;
+                       }
+ 
+                       /* JPEG_MARKER_APP0 */
+-                      if (d[0] == JPEG_MARKER_APP0) {
++                      if (ds >= 3 && d[0] == JPEG_MARKER_APP0) {
+                               d++;
+                               ds--;
+                               l = (d[0] << 8) | d[1];
+@@ -833,7 +833,7 @@
+                       }
+ 
+                       /* JPEG_MARKER_APP1 */
+-                      if (d[0] == JPEG_MARKER_APP1)
++                      if (ds && d[0] == JPEG_MARKER_APP1)
+                               break;
+ 
+                       /* Unknown marker or data. Give up. */
+@@ -841,12 +841,12 @@
+                                 "ExifData", _("EXIF marker not found."));
+                       return;
+               }
+-              d++;
+-              ds--;
+-              if (ds < 2) {
++              if (ds < 3) {
+                       LOG_TOO_SMALL;
+                       return;
+               }
++              d++;
++              ds--;
+               len = (d[0] << 8) | d[1];
+               exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
+                         "We have to deal with %i byte(s) of EXIF data.",
+@@ -872,9 +872,18 @@
+       exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
+                 "Found EXIF header.");
+ 
+-      /* Byte order (offset 6, length 2) */
++      /* Sanity check the data length */
+       if (ds < 14)
+               return;
++
++      /* The JPEG APP1 section can be no longer than 64 KiB (including a
++         16-bit length), so cap the data length to protect against overflow
++         in future offset calculations */
++      fullds = ds;
++      if (ds > 0xfffe)
++              ds = 0xfffe;
++
++      /* Byte order (offset 6, length 2) */
+       if (!memcmp (d + 6, "II", 2))
+               data->priv->order = EXIF_BYTE_ORDER_INTEL;
+       else if (!memcmp (d + 6, "MM", 2))
+@@ -894,24 +903,25 @@
+       exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", 
+                 "IFD 0 at %i.", (int) offset);
+ 
++      /* Sanity check the offset, being careful about overflow */
++      if (offset > ds || offset + 6 + 2 > ds)
++              return;
++
+       /* Parse the actual exif data (usually offset 14 from start) */
+       exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 
0);
+ 
+       /* IFD 1 offset */
+-      if (offset + 6 + 2 > ds) {
+-              return;
+-      }
+       n = exif_get_short (d + 6 + offset, data->priv->order);
+-      if (offset + 6 + 2 + 12 * n + 4 > ds) {
++      if (offset + 6 + 2 + 12 * n + 4 > ds)
+               return;
+-      }
++
+       offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order);
+       if (offset) {
+               exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
+                         "IFD 1 at %i.", (int) offset);
+ 
+               /* Sanity check. */
+-              if (offset > ds - 6) {
++              if (offset > ds || offset + 6 > ds) {
+                       exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA,
+                                 "ExifData", "Bogus offset of IFD1.");
+               } else {
+@@ -925,7 +935,7 @@
+        * space between IFDs. Here is the only place where we have access
+        * to that data.
+        */
+-      interpret_maker_note(data, d, ds);
++      interpret_maker_note(data, d, fullds);
+ 
+       /* Fixup tags if requested */
+       if (data->priv->options & EXIF_DATA_OPTION_FOLLOW_SPECIFICATION)
+
diff --git a/meta/recipes-support/libexif/libexif_0.6.20.bb 
b/meta/recipes-support/libexif/libexif_0.6.20.bb
index 7d8f8fd..25de763 100644
--- a/meta/recipes-support/libexif/libexif_0.6.20.bb
+++ b/meta/recipes-support/libexif/libexif_0.6.20.bb
@@ -9,7 +9,8 @@ PR = "r1"
 SRC_URI = "${SOURCEFORGE_MIRROR}/libexif/libexif-${PV}.tar.bz2 \
          file://0001-libexif-CVE-2012-2813.patch \
          file://0002-libexif-CVE-2012-2812.patch \
-         file://0003-libexif-CVE-2012-2841.patch"
+         file://0003-libexif-CVE-2012-2841.patch \
+         file://0004-libexif-CVE-2012-2836.patch"
 
 SRC_URI[md5sum] = "19844ce6b5d075af16f0d45de1e8a6a3"
 SRC_URI[sha256sum] = 
"a772d20bd8fb9802d7f0d70fde6ac8872f87d0c66c52b0d14026dafcaa83d715"
-- 
1.8.1.2.545.g2f19ada


_______________________________________________
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core

Reply via email to