[oe] [meta-oe][jethro][fido][PATCH] xdelta3: Security fix CVE-2014-9765

Armin Kuster akuster808 at gmail.com
Sun Feb 14 15:56:33 UTC 2016


CVE-2014-9765 xdelta: buffer overflow in main_get_appheader

Signed-off-by: Armin Kuster <akuster808 at gmail.com>
---
 .../xdelta/files/CVE-2014-9765.patch               | 311 +++++++++++++++++++++
 meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb    |   1 +
 2 files changed, 312 insertions(+)
 create mode 100644 meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch

diff --git a/meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch b/meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch
new file mode 100644
index 0000000..572a3c0
--- /dev/null
+++ b/meta-oe/recipes-support/xdelta/files/CVE-2014-9765.patch
@@ -0,0 +1,311 @@
+From ef93ff74203e030073b898c05e8b4860b5d09ef2 Mon Sep 17 00:00:00 2001
+From: "josh.macdonald" <jmacd at users.noreply.github.com>
+Date: Sun, 12 Oct 2014 05:24:22 +0000
+Subject: [PATCH] Add appheader tests; fix buffer overflow in
+ main_get_appheader
+
+Upstream-Status: Backport
+
+This appears to be fixed in xdelta3 3.0.9 and later via
+https://github.com/jmacd/xdelta-devel/commit/ef93ff74203e030073b898c05e8b4860b5d09ef2
+
+CVE: CVE-2014-9765
+Signed-off-by: Armin Kuster <akuster808 at gmail.com>
+
+---
+ xdelta3-main.h |   5 +-
+ xdelta3-test.h | 131 +++++++++++++++++++++++++++++++++++++++----------
+ 2 files changed, 108 insertions(+), 28 deletions(-)
+
+diff --git a/xdelta3-main.h b/xdelta3-main.h
+index 090b7d9..5146b38 100644
+--- a/xdelta3-main.h
++++ b/xdelta3-main.h
+@@ -2810,14 +2810,15 @@ main_get_appheader (xd3_stream *stream, main_file *ifile,
+ 
+   if (appheadsz > 0)
+     {
++      const int kMaxArgs = 4;
+       char *start = (char*)apphead;
+       char *slash;
+       int   place = 0;
+-      char *parsed[4];
++      char *parsed[kMaxArgs];
+ 
+       memset (parsed, 0, sizeof (parsed));
+ 
+-      while ((slash = strchr (start, '/')) != NULL)
++      while ((slash = strchr (start, '/')) != NULL && place < (kMaxArgs-1))
+ 	{
+ 	  *slash = 0;
+ 	  parsed[place++] = start;
+diff --git a/xdelta3-test.h b/xdelta3-test.h
+index e9848b6..0e10251 100644
+--- a/xdelta3-test.h
++++ b/xdelta3-test.h
+@@ -1,5 +1,5 @@
+ /* xdelta 3 - delta compression tools and library Copyright (C) 2001,
+- * 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012.  
++ * 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012.
+  * Joshua P. MacDonald
+  *
+  *  This program is free software; you can redistribute it and/or modify
+@@ -54,7 +54,7 @@ void mt_init(mtrand *mt, uint32_t seed) {
+     /* only MSBs of the array mt[].                        */
+     /* 2002/01/09 modified by Makoto Matsumoto             */
+     mt->mt_buffer_[i] =
+-	(1812433253UL * (mt->mt_buffer_[i-1] ^ 
++	(1812433253UL * (mt->mt_buffer_[i-1] ^
+ 			 (mt->mt_buffer_[i-1] >> 30)) + i);
+   }
+ }
+@@ -69,20 +69,20 @@ uint32_t mt_random (mtrand *mt) {
+     int kk;
+ 
+     for (kk = 0; kk < MT_LEN - MT_IA; kk++) {
+-      y = (mt->mt_buffer_[kk] & UPPER_MASK) | 
++      y = (mt->mt_buffer_[kk] & UPPER_MASK) |
+ 	(mt->mt_buffer_[kk + 1] & LOWER_MASK);
+-      mt->mt_buffer_[kk] = mt->mt_buffer_[kk + MT_IA] ^ 
++      mt->mt_buffer_[kk] = mt->mt_buffer_[kk + MT_IA] ^
+ 	(y >> 1) ^ mag01[y & 0x1UL];
+     }
+     for (;kk < MT_LEN - 1; kk++) {
+-      y = (mt->mt_buffer_[kk] & UPPER_MASK) | 
++      y = (mt->mt_buffer_[kk] & UPPER_MASK) |
+ 	(mt->mt_buffer_[kk + 1] & LOWER_MASK);
+-      mt->mt_buffer_[kk] = mt->mt_buffer_[kk + (MT_IA - MT_LEN)] ^ 
++      mt->mt_buffer_[kk] = mt->mt_buffer_[kk + (MT_IA - MT_LEN)] ^
+ 	(y >> 1) ^ mag01[y & 0x1UL];
+     }
+-    y = (mt->mt_buffer_[MT_LEN - 1] & UPPER_MASK) | 
++    y = (mt->mt_buffer_[MT_LEN - 1] & UPPER_MASK) |
+       (mt->mt_buffer_[0] & LOWER_MASK);
+-    mt->mt_buffer_[MT_LEN - 1] = mt->mt_buffer_[MT_IA - 1] ^ 
++    mt->mt_buffer_[MT_LEN - 1] = mt->mt_buffer_[MT_IA - 1] ^
+       (y >> 1) ^ mag01[y & 0x1UL];
+     mt->mt_index_ = 0;
+   }
+@@ -166,7 +166,7 @@ static int do_cmd (xd3_stream *stream, const char *buf)
+ 	{
+ 	  stream->msg = "abnormal command termination";
+ 	}
+-      return XD3_INTERNAL;
++      return ret;
+     }
+   return 0;
+ }
+@@ -257,8 +257,10 @@ int test_setup (void)
+ static int
+ test_make_inputs (xd3_stream *stream, xoff_t *ss_out, xoff_t *ts_out)
+ {
+-  usize_t ts = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2;
+-  usize_t ss = (mt_random (&static_mtrand) % TEST_FILE_MEAN) + TEST_FILE_MEAN / 2;
++  usize_t ts = (mt_random (&static_mtrand) % TEST_FILE_MEAN) +
++    TEST_FILE_MEAN / 2;
++  usize_t ss = (mt_random (&static_mtrand) % TEST_FILE_MEAN) +
++    TEST_FILE_MEAN / 2;
+   uint8_t *buf = (uint8_t*) malloc (ts + ss), *sbuf = buf, *tbuf = buf + ss;
+   usize_t sadd = 0, sadd_max = (usize_t)(ss * TEST_ADD_RATIO);
+   FILE  *tf = NULL, *sf = NULL;
+@@ -409,7 +411,7 @@ test_compare_files (const char* tgt, const char *rec)
+ 	{
+ 	  if (obuf[i] != rbuf[i])
+  	    {
+-	      XPR(NT "byte %u (read %u @ %"Q"u) %d != %d\n", 
++	      XPR(NT "byte %u (read %u @ %"Q"u) %d != %d\n",
+ 		  (int)i, (int)oc, offset, obuf[i], rbuf[i]);
+ 	      diffs++;
+ 	      return XD3_INTERNAL;
+@@ -421,7 +423,7 @@ test_compare_files (const char* tgt, const char *rec)
+ 
+     fclose (orig);
+     fclose (recons);
+-    if (diffs != 0) 
++    if (diffs != 0)
+       {
+ 	return XD3_INTERNAL;
+       }
+@@ -429,12 +431,12 @@ test_compare_files (const char* tgt, const char *rec)
+ }
+ 
+ static int
+-test_save_copy (const char *origname)
++test_copy_to (const char *from, const char *to)
+ {
+   char buf[TESTBUFSIZE];
+   int ret;
+ 
+-  snprintf_func (buf, TESTBUFSIZE, "cp -f %s %s", origname, TEST_COPY_FILE);
++  snprintf_func (buf, TESTBUFSIZE, "cp -f %s %s", from, to);
+ 
+   if ((ret = system (buf)) != 0)
+     {
+@@ -445,6 +447,12 @@ test_save_copy (const char *origname)
+ }
+ 
+ static int
++test_save_copy (const char *origname)
++{
++  return test_copy_to(origname, TEST_COPY_FILE);
++}
++
++static int
+ test_file_size (const char* file, xoff_t *size)
+ {
+   struct stat sbuf;
+@@ -499,7 +507,7 @@ test_read_integer_error (xd3_stream *stream, usize_t trunto, const char *msg)
+   inp = buf->base;
+   max = buf->base + buf->next - trunto;
+ 
+-  if ((ret = xd3_read_uint32_t (stream, & inp, max, & rval)) != 
++  if ((ret = xd3_read_uint32_t (stream, & inp, max, & rval)) !=
+       XD3_INVALID_INPUT ||
+       !MSG_IS (msg))
+     {
+@@ -1654,11 +1662,11 @@ test_compressed_stream_overflow (xd3_stream *stream, int ignore)
+   if ((buf = (uint8_t*) malloc (TWO_MEGS_AND_DELTA)) == NULL) { return ENOMEM; }
+ 
+   memset (buf, 0, TWO_MEGS_AND_DELTA);
+-  for (i = 0; i < (2 << 20); i += 256) 
++  for (i = 0; i < (2 << 20); i += 256)
+     {
+       int j;
+       int off = mt_random(& static_mtrand) % 10;
+-      for (j = 0; j < 256; j++) 
++      for (j = 0; j < 256; j++)
+ 	{
+ 	  buf[i + j] = j + off;
+ 	}
+@@ -1683,11 +1691,11 @@ test_compressed_stream_overflow (xd3_stream *stream, int ignore)
+     }
+ 
+   /* Test transfer of exactly 32bits worth of data. */
+-  if ((ret = test_streaming (stream, 
+-			     buf, 
+-			     buf + (1 << 20), 
+-			     buf + (2 << 20), 
+-			     1 << 12))) 
++  if ((ret = test_streaming (stream,
++			     buf,
++			     buf + (1 << 20),
++			     buf + (2 << 20),
++			     1 << 12)))
+     {
+       goto fail;
+     }
+@@ -1889,7 +1897,7 @@ test_recode_command2 (xd3_stream *stream, int has_source,
+     }
+ 
+   /* First encode */
+-  snprintf_func (ecmd, TESTBUFSIZE, "%s %s -f %s %s %s %s %s %s %s", 
++  snprintf_func (ecmd, TESTBUFSIZE, "%s %s -f %s %s %s %s %s %s %s",
+ 	    program_name, test_softcfg_str,
+ 	    has_adler32 ? "" : "-n ",
+ 	    has_apphead ? "-A=encode_apphead " : "-A= ",
+@@ -1910,7 +1918,7 @@ test_recode_command2 (xd3_stream *stream, int has_source,
+   snprintf_func (recmd, TESTBUFSIZE,
+ 	    "%s recode %s -f %s %s %s %s %s", program_name, test_softcfg_str,
+ 	    recoded_adler32 ? "" : "-n ",
+-	    !change_apphead ? "" : 
++	    !change_apphead ? "" :
+ 	        (recoded_apphead ? "-A=recode_apphead " : "-A= "),
+ 	    recoded_secondary ? "-S djw " : "-S none ",
+ 	    TEST_DELTA_FILE,
+@@ -2361,6 +2369,76 @@ test_no_output (xd3_stream *stream, int ignore)
+   return 0;
+ }
+ 
++/* This tests that the default appheader works */
++static int
++test_appheader (xd3_stream *stream, int ignore)
++{
++  int i;
++  int ret;
++  char buf[TESTBUFSIZE];
++  char bogus[TESTBUFSIZE];
++  xoff_t ssize, tsize;
++  test_setup ();
++
++  if ((ret = test_make_inputs (stream, &ssize, &tsize))) { return ret; }
++
++  snprintf_func (buf, TESTBUFSIZE, "%s -q -f -e -s %s %s %s", program_name,
++		 TEST_SOURCE_FILE, TEST_TARGET_FILE, TEST_DELTA_FILE);
++  if ((ret = do_cmd (stream, buf))) { return ret; }
++
++  if ((ret = test_copy_to (program_name, TEST_RECON2_FILE))) { return ret; }
++
++  snprintf_func (buf, TESTBUFSIZE, "chmod 0700 %s", TEST_RECON2_FILE);
++  if ((ret = do_cmd (stream, buf))) { return ret; }
++
++  if ((ret = test_save_copy (TEST_TARGET_FILE))) { return ret; }
++  if ((ret = test_copy_to (TEST_SOURCE_FILE, TEST_TARGET_FILE))) { return ret; }
++
++  if ((ret = test_compare_files (TEST_TARGET_FILE, TEST_COPY_FILE)) == 0)
++    {
++      return XD3_INVALID;  // I.e., files are different!
++    }
++
++  // Test that the target file is restored.
++  snprintf_func (buf, TESTBUFSIZE, "(cd /tmp && %s -q -f -d %s)",
++		 TEST_RECON2_FILE,
++		 TEST_DELTA_FILE);
++  if ((ret = do_cmd (stream, buf))) { return ret; }
++
++  if ((ret = test_compare_files (TEST_TARGET_FILE, TEST_COPY_FILE)) != 0)
++    {
++      return ret;
++    }
++
++  // Test a malicious string w/ entries > 4 in the appheader by having
++  // the encoder write it:
++  for (i = 0; i < TESTBUFSIZE / 4; ++i)
++    {
++      bogus[2*i] = 'G';
++      bogus[2*i+1] = '/';
++    }
++  bogus[TESTBUFSIZE/2-1] = 0;
++
++  snprintf_func (buf, TESTBUFSIZE, 
++		 "%s -q -f -A=%s -e -s %s %s %s", program_name, bogus,
++		 TEST_SOURCE_FILE, TEST_TARGET_FILE, TEST_DELTA_FILE);
++  if ((ret = do_cmd (stream, buf))) { return ret; }
++  // Then read it:
++  snprintf_func (buf, TESTBUFSIZE, "(cd /tmp && %s -q -f -d %s)",
++		 TEST_RECON2_FILE,
++		 TEST_DELTA_FILE);
++  if ((ret = do_cmd (stream, buf)) == 0) 
++    { 
++      return XD3_INVALID;  // Impossible
++    }
++  if (!WIFEXITED(ret))
++    {
++      return XD3_INVALID;  // Must have crashed!
++    }
++
++  return 0;
++}
++
+ /***********************************************************************
+  Source identical optimization
+  ***********************************************************************/
+@@ -2603,7 +2681,7 @@ test_string_matching (xd3_stream *stream, int ignore)
+ 	    default: CHECK(0);
+ 	    }
+ 
+-	  snprintf_func (rptr, rbuf+TESTBUFSIZE-rptr, "%d/%d", 
++	  snprintf_func (rptr, rbuf+TESTBUFSIZE-rptr, "%d/%d",
+ 			 inst->pos, inst->size);
+ 	  rptr += strlen (rptr);
+ 
+@@ -2848,6 +2926,7 @@ xd3_selftest (void)
+   DO_TEST (force_behavior, 0, 0);
+   DO_TEST (stdout_behavior, 0, 0);
+   DO_TEST (no_output, 0, 0);
++  DO_TEST (appheader, 0, 0);
+   DO_TEST (command_line_arguments, 0, 0);
+ 
+ #if EXTERNAL_COMPRESSION
+-- 
+2.3.5
+
diff --git a/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb b/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb
index baa92e4..2ddf78a 100644
--- a/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb
+++ b/meta-oe/recipes-support/xdelta/xdelta3_3.0.8.bb
@@ -10,6 +10,7 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833"
 SRC_URI = "http://xdelta.googlecode.com/files/${BPN}-${PV}.tar.xz \
            file://compilation-fix.patch \
            file://with-liblzma-configure-option.patch \
+           file://CVE-2014-9765.patch \
 "
 SRC_URI[md5sum] = "c3ae3286ce4193de8e03d5bcaccf3bc3"
 SRC_URI[sha256sum] = "3a86f29c95664fb44b8a40ff22d9bcc3e87aa8c01f0ff75931a7fa78ed3d2e55"
-- 
2.3.5




More information about the Openembedded-devel mailing list