Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian....@packages.debian.org
Usertags: pu

Hello release team,

as mentioned in #-1, I'd like to fix the existing non-dsa
issues in busybox.

For *jessie*, https://security-tracker.debian.org/busybox lists the
following issues I'd like to fix in an upcoming point release.
Those marked "#" are the same as for stretch (#877258).

# TEMP-0803097-A74121, #803097
  busybox: pointer misuse unziping files

  Fix: 
https://git.busybox.net/busybox/commit/?id=1de25a6e87e0e627aa34298105a3d17c60a1f44e
  Patch: cherry-pick.1_24_0-68-g1de25a6.unzip-test-for-bad-archive-segving.patch

# CVE-2016-2148, #818497
  Heap-based buffer overflow in the DHCP client (udhcpc) in BusyBox
  before 1.25.0 allows remote attackers to have unspecified impact via
  vectors involving OPTION_6RD parsing.

  Fix: 
https://git.busybox.net/busybox/commit/?id=352f79acbd759c14399e39baef21fc4ffe180ac2
  Patch: 
cherry-pick.1_24_0-139-g352f79a.udhcpc-fix-option-6rd-parsing-could-overflow-its-malloced-buffer.patch

# CVE-2016-2147, #818499
  Integer overflow in the DHCP client (udhcpc) in BusyBox before 1.25.0
  allows remote attackers to cause a denial of service (crash) via a
  malformed RFC1035-encoded domain name, which triggers an
  out-of-bounds heap write.

  Fix: 
https://git.busybox.net/busybox/commit/?id=d474ffc68290e0a83651c4432eeabfa62cd51e87
  Patch: 
cherry-pick.1_24_0-152-gd474ffc.udhcp-fix-a-segv-on-malformed-rfc1035-encoded-domain-name.patch

* CVE-2014-9645, #776186
  The add_probe function in modutils/modprobe.c in BusyBox before
  1.23.0 allows local users to bypass intended restrictions on loading
  kernel modules via a / (slash) character in a module name, as
  demonstrated by an "ifconfig /usbserial up" command or a "mount -t
  /snd_pcm none /" command.

  Fix: 
https://git.busybox.net/busybox/commit/?id=4e314faa0aecb66717418e9a47a4451aec59262b
  Patch: 
cherry-pick.1_22_0-220-g4e314fa.modprobe-rmmod-reject-module-names-with-slashes.patch

# CVE-2011-5325, #802702
  Directory traversal vulnerability in the BusyBox implementation of
  tar before 1.22.0 v5 allows remote attackers to point to files
  outside the current working directory via a symlink.

  Fix: 
https://git.busybox.net/busybox/commit/?id=b920a38dc0a87f5884444d4731a8b887b5e16018
  Patch: 
cherry-pick.1_27_0-148-gb920a38dc.tar-postpone-creation-of-symlinks-with-suspicious-targets.patch
  Also the following was needed as a prerequisite for the tests:
  
cherry-pick.1_24_0-44-ga960748.tar-add-a-test-that-we-dont-write-into-symlinks.patch

Find the debdiff attached.

Cheers,

    Christoph

-- System Information:
Debian Release: 8.9
  APT prefers oldstable-updates
  APT policy: (500, 'oldstable-updates'), (500, 'oldstable-proposed-updates'), 
(500, 'oldstable')
Architecture: amd64 (x86_64)
diff -Nru busybox-1.22.0/debian/changelog busybox-1.22.0/debian/changelog
--- busybox-1.22.0/debian/changelog     2015-02-17 18:30:02.000000000 +0100
+++ busybox-1.22.0/debian/changelog     2017-09-25 22:57:20.000000000 +0200
@@ -1,3 +1,17 @@
+busybox (1:1.22.0-9+deb8u2) jessie; urgency=medium
+
+  * Reject module names with slashes.
+    Closes: #776186 [CVE-2014-9645]
+  * Fix pointer misuse unziping files. Closes: #803097
+  * Fix Heap-based buffer overflow in the DHCP client.
+    Closes: #818497 [CVE-2016-2148]
+  * Fix integer overflow in the DHCP client (udhcpc).
+    Closes: #818499 [CVE-2016-2147]
+  * Fix directory traversal vulnerability in tar implementation.
+    Closes: #802702 [CVE-2011-5325]
+
+ -- Christoph Biedl <debian.a...@manchmal.in-ulm.de>  Mon, 25 Sep 2017 
22:57:20 +0200
+
 busybox (1:1.22.0-9+deb8u1) jessie; urgency=medium
 
   * Non-maintainer upload.
diff -Nru 
busybox-1.22.0/debian/patches/cherry-pick.1_22_0-220-g4e314fa.modprobe-rmmod-reject-module-names-with-slashes.patch
 
busybox-1.22.0/debian/patches/cherry-pick.1_22_0-220-g4e314fa.modprobe-rmmod-reject-module-names-with-slashes.patch
--- 
busybox-1.22.0/debian/patches/cherry-pick.1_22_0-220-g4e314fa.modprobe-rmmod-reject-module-names-with-slashes.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
busybox-1.22.0/debian/patches/cherry-pick.1_22_0-220-g4e314fa.modprobe-rmmod-reject-module-names-with-slashes.patch
 2017-09-25 22:57:20.000000000 +0200
@@ -0,0 +1,27 @@
+Subject: Modprobe,rmmod: reject module names with slashes
+ID: CVE-2014-9645
+Origin: 1_22_0-220-g4e314fa
+Upstream-Author: Denys Vlasenko <vda.li...@googlemail.com>
+Date: Thu Nov 20 18:24:33 2014 +0100
+Bug-Debian: https://bugs.debian.org/776186
+
+--- a/modutils/modprobe.c
++++ b/modutils/modprobe.c
+@@ -239,6 +239,17 @@
+ {
+       struct module_entry *m;
+ 
++      /*
++       * get_or_add_modentry() strips path from name and works
++       * on remaining basename.
++       * This would make "rmmod dir/name" and "modprobe dir/name"
++       * to work like "rmmod name" and "modprobe name",
++       * which is wrong, and can be abused via implicit modprobing:
++       * "ifconfig /usbserial up" tries to modprobe netdev-/usbserial.
++       */
++      if (strchr(name, '/'))
++              bb_error_msg_and_die("malformed module name '%s'", name);
++
+       m = get_or_add_modentry(name);
+       if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS))
+        && (m->flags & (MODULE_FLAG_LOADED | MODULE_FLAG_BUILTIN))
diff -Nru 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-139-g352f79a.udhcpc-fix-option-6rd-parsing-could-overflow-its-malloced-buffer.patch
 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-139-g352f79a.udhcpc-fix-option-6rd-parsing-could-overflow-its-malloced-buffer.patch
--- 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-139-g352f79a.udhcpc-fix-option-6rd-parsing-could-overflow-its-malloced-buffer.patch
        1970-01-01 01:00:00.000000000 +0100
+++ 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-139-g352f79a.udhcpc-fix-option-6rd-parsing-could-overflow-its-malloced-buffer.patch
        2017-09-25 22:57:20.000000000 +0200
@@ -0,0 +1,58 @@
+Subject: Udhcpc: fix OPTION_6RD parsing (could overflow its malloced buffer)
+ID: CVE-2016-2148
+Origin: 1_24_0-139-g352f79a
+Upstream-Author: Denys Vlasenko <vda.li...@googlemail.com>
+Date: Fri Feb 26 15:54:56 2016 +0100
+Bug-Debian: https://bugs.debian.org/818497 
+
+--- a/networking/udhcp/common.c
++++ b/networking/udhcp/common.c
+@@ -140,7 +140,7 @@
+  * udhcp_str2optset: to determine how many bytes to allocate.
+  * xmalloc_optname_optval: to estimate string length
+  * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type])
+- * is the number of elements, multiply in by one element's string width
++ * is the number of elements, multiply it by one element's string width
+  * (len_of_option_as_string[opt_type]) and you know how wide string you need.
+  */
+ const uint8_t dhcp_option_lengths[] ALIGN1 = {
+@@ -160,7 +160,18 @@
+       [OPTION_S32] =     4,
+       /* Just like OPTION_STRING, we use minimum length here */
+       [OPTION_STATIC_ROUTES] = 5,
+-      [OPTION_6RD] =    22,  /* ignored by udhcp_str2optset */
++      [OPTION_6RD] =    12,  /* ignored by udhcp_str2optset */
++      /* The above value was chosen as follows:
++       * len_of_option_as_string[] for this option is >60: it's a string of 
the form
++       * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ".
++       * Each additional ipv4 address takes 4 bytes in binary option and 
appends
++       * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 
4
++       * but this severely overestimates string length: instead of 16 bytes,
++       * it adds >60 for every 4 bytes in binary option.
++       * We cheat and declare here that option is in units of 12 bytes.
++       * This adds more than 60 bytes for every three ipv4 addresses - more 
than enough.
++       * (Even 16 instead of 12 should work, but let's be paranoid).
++       */
+ };
+ 
+ 
+--- a/networking/udhcp/dhcpc.c
++++ b/networking/udhcp/dhcpc.c
+@@ -99,7 +99,7 @@
+       [OPTION_IP              ] = sizeof("255.255.255.255 "),
+       [OPTION_IP_PAIR         ] = sizeof("255.255.255.255 ") * 2,
+       [OPTION_STATIC_ROUTES   ] = sizeof("255.255.255.255/32 255.255.255.255 
"),
+-      [OPTION_6RD             ] = sizeof("32 128 
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
++      [OPTION_6RD             ] = sizeof("132 128 
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "),
+       [OPTION_STRING          ] = 1,
+       [OPTION_STRING_HOST     ] = 1,
+ #if ENABLE_FEATURE_UDHCP_RFC3397
+@@ -206,7 +206,7 @@
+       type = optflag->flags & OPTION_TYPE_MASK;
+       optlen = dhcp_option_lengths[type];
+       upper_length = len_of_option_as_string[type]
+-              * ((unsigned)(len + optlen - 1) / (unsigned)optlen);
++              * ((unsigned)(len + optlen) / (unsigned)optlen);
+ 
+       dest = ret = xmalloc(upper_length + strlen(opt_name) + 2);
+       dest += sprintf(ret, "%s=", opt_name);
diff -Nru 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-152-gd474ffc.udhcp-fix-a-segv-on-malformed-rfc1035-encoded-domain-name.patch
 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-152-gd474ffc.udhcp-fix-a-segv-on-malformed-rfc1035-encoded-domain-name.patch
--- 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-152-gd474ffc.udhcp-fix-a-segv-on-malformed-rfc1035-encoded-domain-name.patch
       1970-01-01 01:00:00.000000000 +0100
+++ 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-152-gd474ffc.udhcp-fix-a-segv-on-malformed-rfc1035-encoded-domain-name.patch
       2017-09-25 22:57:20.000000000 +0200
@@ -0,0 +1,45 @@
+Subject: Udhcp: fix a SEGV on malformed RFC1035-encoded domain name
+ID: CVE-2016-2147
+Origin: 1_24_0-152-gd474ffc
+Upstream-Author: Denys Vlasenko <vda.li...@googlemail.com>
+Date: Thu Mar 10 11:47:58 2016 +0100
+Bug-Debian: https://bugs.debian.org/818499
+
+--- a/networking/udhcp/domain_codec.c
++++ b/networking/udhcp/domain_codec.c
+@@ -63,11 +63,10 @@
+                               if (crtpos + *c + 1 > clen) /* label too long? 
abort */
+                                       return NULL;
+                               if (dst)
+-                                      memcpy(dst + len, c + 1, *c);
++                                      /* \3com ---> "com." */
++                                      ((char*)mempcpy(dst + len, c + 1, 
*c))[0] = '.';
+                               len += *c + 1;
+                               crtpos += *c + 1;
+-                              if (dst)
+-                                      dst[len - 1] = '.';
+                       } else {
+                               /* NUL: end of current domain name */
+                               if (retpos == 0) {
+@@ -78,7 +77,10 @@
+                                       crtpos = retpos;
+                                       retpos = depth = 0;
+                               }
+-                              if (dst)
++                              if (dst && len != 0)
++                                      /* \4host\3com\0\4host and we are at \0:
++                                       * \3com was converted to "com.", 
change dot to space.
++                                       */
+                                       dst[len - 1] = ' ';
+                       }
+ 
+@@ -228,6 +230,9 @@
+       int len;
+       uint8_t *encoded;
+ 
++        uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 };
++        printf("NUL:'%s'\n",   dname_dec(str, 6, ""));
++
+ #define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), 
sizeof(encoded), (pre))
+       printf("'%s'\n",       DNAME_DEC("\4host\3com\0", "test1:"));
+       printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", ""));
diff -Nru 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-44-ga960748.tar-add-a-test-that-we-dont-write-into-symlinks.patch
 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-44-ga960748.tar-add-a-test-that-we-dont-write-into-symlinks.patch
--- 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-44-ga960748.tar-add-a-test-that-we-dont-write-into-symlinks.patch
  1970-01-01 01:00:00.000000000 +0100
+++ 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-44-ga960748.tar-add-a-test-that-we-dont-write-into-symlinks.patch
  2017-09-25 22:57:20.000000000 +0200
@@ -0,0 +1,59 @@
+Subject: Tar: add a test that we don't write into symlinks
+Origin: 1_24_0-44-ga960748
+Upstream-Author: Denys Vlasenko <vda.li...@googlemail.com>
+Date: Thu Oct 22 16:37:01 2015 +0200
+
+    [ Prerequisite for CVE-2011-5325 fix ]
+
+--- a/testsuite/tar.tests
++++ b/testsuite/tar.tests
+@@ -246,6 +246,49 @@
+ "" ""
+ SKIP=
+ 
++# attack.tar.bz2 has symlink pointing to a system file
++# followed by a regular file with the same name
++# containing "root::0:0::/root:/bin/sh":
++#  lrwxrwxrwx root/root passwd -> /tmp/passwd
++#  -rw-r--r-- root/root passwd
++# naive tar implementation may end up creating the symlink
++# and then writing into it.
++# The correct implementation unlinks target before
++# creating the second file.
++# We test that /tmp/passwd remains empty:
++optional UUDECODE FEATURE_SEAMLESS_BZ2
++testing "tar does not extract into symlinks" "\
++>>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat 
/tmp/passwd; echo \$?
++" "\
++0
++" \
++"" "\
++begin-base64 644 attack.tar.bz2
++QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0
++po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL
++DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4
++l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI=
++====
++"
++SKIP=
++# And same with -k
++optional UUDECODE FEATURE_SEAMLESS_BZ2
++testing "tar -k does not extract into symlinks" "\
++>>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat 
/tmp/passwd; echo \$?
++" "\
++tar: can't open 'passwd': File exists
++0
++" \
++"" "\
++begin-base64 644 attack.tar.bz2
++QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0
++po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL
++DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4
++l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI=
++====
++"
++SKIP=
++
+ 
+ cd .. && rm -rf tar.tempdir || exit 1
+ 
diff -Nru 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-68-g1de25a6.unzip-test-for-bad-archive-segving.patch
 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-68-g1de25a6.unzip-test-for-bad-archive-segving.patch
--- 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-68-g1de25a6.unzip-test-for-bad-archive-segving.patch
       1970-01-01 01:00:00.000000000 +0100
+++ 
busybox-1.22.0/debian/patches/cherry-pick.1_24_0-68-g1de25a6.unzip-test-for-bad-archive-segving.patch
       2017-09-25 22:57:20.000000000 +0200
@@ -0,0 +1,96 @@
+Subject: Unzip: test for bad archive SEGVing
+ID: TEMP-0803097-A74121
+Origin: 1_24_0-68-g1de25a6
+Upstream-Author: Denys Vlasenko <vda.li...@googlemail.com>
+Date: Mon Oct 26 19:33:05 2015 +0100
+Bug-Debian: https://bugs.debian.org/803097
+
+--- a/archival/libarchive/decompress_gunzip.c
++++ b/archival/libarchive/decompress_gunzip.c
+@@ -305,11 +305,12 @@
+       unsigned i;             /* counter, current code */
+       unsigned j;             /* counter */
+       int k;                  /* number of bits in current code */
+-      unsigned *p;            /* pointer into c[], b[], or v[] */
++      const unsigned *p;      /* pointer into c[], b[], or v[] */
+       huft_t *q;              /* points to current table */
+       huft_t r;               /* table entry for structure assignment */
+       huft_t *u[BMAX];        /* table stack */
+       unsigned v[N_MAX];      /* values in order of bit length */
++      unsigned v_end;
+       int ws[BMAX + 1];       /* bits decoded stack */
+       int w;                  /* bits decoded */
+       unsigned x[BMAX + 1];   /* bit offsets, then code stack */
+@@ -324,7 +325,7 @@
+ 
+       /* Generate counts for each bit length */
+       memset(c, 0, sizeof(c));
+-      p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */
++      p = b;
+       i = n;
+       do {
+               c[*p]++; /* assume all entries <= BMAX */
+@@ -365,12 +366,14 @@
+       }
+ 
+       /* Make a table of values in order of bit lengths */
+-      p = (unsigned *) b;
++      p = b;
+       i = 0;
++      v_end = 0;
+       do {
+               j = *p++;
+               if (j != 0) {
+                       v[x[j]++] = i;
++                      v_end = x[j];
+               }
+       } while (++i < n);
+ 
+@@ -432,7 +435,7 @@
+ 
+                       /* set up table entry in r */
+                       r.b = (unsigned char) (k - w);
+-                      if (p >= v + n) {
++                      if (p >= v + v_end) { // Was "if (p >= v + n)" but v[] 
can be shorter!
+                               r.e = 99; /* out of values--invalid code */
+                       } else if (*p < s) {
+                               r.e = (unsigned char) (*p < 256 ? 16 : 15);     
/* 256 is EOB code */
+--- a/testsuite/unzip.tests
++++ b/testsuite/unzip.tests
+@@ -7,7 +7,7 @@
+ 
+ . ./testing.sh
+ 
+-# testing "test name" "options" "expected result" "file input" "stdin"
++# testing "test name" "commands" "expected result" "file input" "stdin"
+ #   file input will be file called "input"
+ #   test can create a file "actual" instead of writing to stdout
+ 
+@@ -30,6 +30,27 @@
+ rmdir foo
+ rm foo.zip
+ 
++# File containing some damaged encrypted stream
++testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \
++"Archive:  bad.zip
++  inflating: ]3j½r«IK-%Ix
++unzip: inflate error
++1
++" \
++"" "\
++begin-base64 644 bad.zip
++UEsDBBQAAgkIAAAAIQA5AAAANwAAADwAAAAQAAcAXTNqwr1ywqtJGxJLLSVJ
++eCkBD0AdKBk8JzQsIj01JC0/ORJQSwMEFAECCAAAAAAhADoAAAAPAAAANgAA
++AAwAAQASw73Ct1DCokohPXQiNjoUNTUiHRwgLT4WHlBLAQIQABQAAggIAAAA
++oQA5AAAANwAAADwAAAAQQAcADAAAACwAMgCAAAAAAABdM2rCvXLCq0kbEkst
++JUl4KQEPQB0oGSY4Cz4QNgEnJSYIPVBLAQIAABQAAggAAAAAIQAqAAAADwAA
++BDYAAAAMAAEADQAAADIADQAAAEEAAAASw73Ct1DKokohPXQiNzA+FAI1HCcW
++NzITNFBLBQUKAC4JAA04Cw0EOhZQSwUGAQAABAIAAgCZAAAAeQAAAAIALhM=
++====
++"
++
++rm *
++
+ # Clean up scratch directory.
+ 
+ cd ..
diff -Nru 
busybox-1.22.0/debian/patches/cherry-pick.1_27_0-148-gb920a38.tar-postpone-creation-of-symlinks-with-suspicious-targets.patch
 
busybox-1.22.0/debian/patches/cherry-pick.1_27_0-148-gb920a38.tar-postpone-creation-of-symlinks-with-suspicious-targets.patch
--- 
busybox-1.22.0/debian/patches/cherry-pick.1_27_0-148-gb920a38.tar-postpone-creation-of-symlinks-with-suspicious-targets.patch
       1970-01-01 01:00:00.000000000 +0100
+++ 
busybox-1.22.0/debian/patches/cherry-pick.1_27_0-148-gb920a38.tar-postpone-creation-of-symlinks-with-suspicious-targets.patch
       2017-09-25 22:57:20.000000000 +0200
@@ -0,0 +1,347 @@
+Subject: Tar: postpone creation of symlinks with "suspicious" targets. Closes 
8411
+ID: CVE-2011-5325
+Origin: 1_27_0-148-gb920a38dc
+Upstream-Author: Denys Vlasenko <vda.li...@googlemail.com>
+Date: Mon Jul 24 17:20:13 2017 +0200
+Bug-Debian: https://bugs.debian.org/802702
+
+--- a/archival/libarchive/data_extract_all.c
++++ b/archival/libarchive/data_extract_all.c
+@@ -143,6 +143,34 @@
+       case S_IFLNK:
+               /* Symlink */
+ //TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
++
++              /* To avoid a directory traversal attack via symlinks,
++               * for certain link targets postpone creation of symlinks.
++               *
++               * For example, consider a .tar created via:
++               *  $ tar cvf bug.tar anything.txt
++               *  $ ln -s /tmp symlink
++               *  $ tar --append -f bug.tar symlink
++               *  $ rm symlink
++               *  $ mkdir symlink
++               *  $ tar --append -f bug.tar symlink/evil.py
++               *
++               * This will result in an archive that contains:
++               *  $ tar --list -f bug.tar
++               *  anything.txt
++               *  symlink [-> /tmp]
++               *  symlink/evil.py
++               *
++               * Untarring bug.tar would otherwise place evil.py in '/tmp'.
++               */
++              if (file_header->link_target[0] == '/'
++               || strstr(file_header->link_target, "..")
++              ) {
++                      llist_add_to(&archive_handle->symlink_placeholders,
++                              xasprintf("%s%c%s", file_header->name, '\0', 
file_header->link_target)
++                      );
++                      break;
++              }
+               res = symlink(file_header->link_target, file_header->name);
+               if ((res == -1)
+                && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
+--- a/archival/tar.c
++++ b/archival/tar.c
+@@ -22,24 +22,6 @@
+  *
+  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+  */
+-/* TODO: security with -C DESTDIR option can be enhanced.
+- * Consider tar file created via:
+- * $ tar cvf bug.tar anything.txt
+- * $ ln -s /tmp symlink
+- * $ tar --append -f bug.tar symlink
+- * $ rm symlink
+- * $ mkdir symlink
+- * $ tar --append -f bug.tar symlink/evil.py
+- *
+- * This will result in an archive which contains:
+- * $ tar --list -f bug.tar
+- * anything.txt
+- * symlink
+- * symlink/evil.py
+- *
+- * Untarring it puts evil.py in '/tmp' even if the -C DESTDIR is given.
+- * This doesn't feel right, and IIRC GNU tar doesn't do that.
+- */
+ 
+ //config:config TAR
+ //config:     bool "tar"
+@@ -309,6 +291,23 @@
+       xwrite(fd, hp, sizeof(*hp));
+ }
+ 
++static void replace_symlink_placeholders(llist_t *list)
++{
++      while (list) {
++              char *target;
++
++              target = list->data + strlen(list->data) + 1;
++              if (symlink(target, list->data)) {
++                      /* shared message */
++                      bb_error_msg_and_die("can't create %slink '%s' to '%s'",
++                              "sym",
++                              list->data, target
++                      );
++              }
++              list = list->link;
++      }
++}
++
+ #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
+ static void writeLongname(int fd, int type, const char *name, int dir)
+ {
+@@ -1205,6 +1204,8 @@
+       while (get_header_tar(tar_handle) == EXIT_SUCCESS)
+               bb_got_signal = EXIT_SUCCESS; /* saw at least one header, good 
*/
+ 
++      replace_symlink_placeholders(tar_handle->symlink_placeholders);
++
+       /* Check that every file that should have been extracted was */
+       while (tar_handle->accept) {
+               if (!find_list_entry(tar_handle->reject, 
tar_handle->accept->data)
+--- /dev/null
++++ b/archival/tar_symlink_attack
+@@ -0,0 +1,16 @@
++#!/bin/sh
++# Makes "symlink attack" tarball (needs GNU tar for --append)
++
++true >anything.txt
++tar cvf tar_symlink_attack.tar anything.txt
++rm anything.txt
++
++ln -s /tmp symlink
++tar --append -f tar_symlink_attack.tar symlink
++rm symlink
++
++mkdir symlink
++echo BUG >symlink/bb_test_evilfile
++tar --append -f tar_symlink_attack.tar symlink/bb_test_evilfile
++rm symlink/bb_test_evilfile
++rmdir symlink
+--- a/include/bb_archive.h
++++ b/include/bb_archive.h
+@@ -64,6 +64,9 @@
+       /* Currently processed file's header */
+       file_header_t *file_header;
+ 
++      /* List of symlink placeholders */
++      llist_t *symlink_placeholders;
++
+       /* Process the header component, e.g. tar -t */
+       void FAST_FUNC (*action_header)(const file_header_t *);
+ 
+--- a/testsuite/tar.tests
++++ b/testsuite/tar.tests
+@@ -10,9 +10,6 @@
+ unset LC_ALL
+ umask 022
+ 
+-rm -rf tar.tempdir 2>/dev/null
+-mkdir tar.tempdir && cd tar.tempdir || exit 1
+-
+ # testing "test name" "script" "expected result" "file input" "stdin"
+ 
+ testing "Empty file is not a tarball" '\
+@@ -53,9 +50,18 @@
+ "" ""
+ SKIP=
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
++# "tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 
input_dir/ input":
++# GNU tar 1.26 records as hardlinks:
++#  input_hard2 -> input_hard1
++#  input_hard1 -> input_hard1 (!!!)
++#  input_dir/file -> input_dir/file
++#  input -> input
++# As of 1.24.0, we don't record last two: for them, nlink==1
++# and we check for "hardlink"ness only files with nlink!=1
++# We also don't use "hrw-r--r--" notation for hardlinks in "tar tv" listing.
+ optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES
+ testing "tar hardlinks and repeated files" '\
+-rm -rf input_* test.tar 2>/dev/null
+ >input_hard1
+ ln input_hard1 input_hard2
+ mkdir input_dir
+@@ -64,6 +70,7 @@
+ chmod    755 input_dir
+ tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 
input_dir/ input
+ tar tvf test.tar | sed "s/.*[0-9] input/input/"
++rm -rf input_dir
+ tar xf test.tar 2>&1
+ echo Ok: $?
+ ls -l . input_dir/* | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/"
+@@ -85,10 +92,11 @@
+ " \
+ "" ""
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES
+ testing "tar hardlinks mode" '\
+-rm -rf input_* test.tar 2>/dev/null
+ >input_hard1
+ chmod 741 input_hard1
+ ln input_hard1 input_hard2
+@@ -118,10 +126,11 @@
+ " \
+ "" ""
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES
+ testing "tar symlinks mode" '\
+-rm -rf input_* test.tar 2>/dev/null
+ >input_file
+ chmod 741 input_file
+ ln -s input_file input_soft
+@@ -149,10 +158,11 @@
+ " \
+ "" ""
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ optional FEATURE_TAR_CREATE FEATURE_TAR_LONG_OPTIONS
+ testing "tar --overwrite" "\
+-rm -rf input_* test.tar 2>/dev/null
+ ln input input_hard
+ tar cf test.tar input_hard
+ echo WRONG >input
+@@ -164,12 +174,13 @@
+ " \
+ "Ok\n" ""
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ test x"$SKIP_KNOWN_BUGS" = x"" && {
+ # Needs to be run under non-root for meaningful test
+ optional FEATURE_TAR_CREATE
+ testing "tar writing into read-only dir" '\
+-rm -rf input_* test.tar 2>/dev/null
+ mkdir input_dir
+ >input_dir/input_file
+ chmod 550 input_dir
+@@ -191,7 +202,9 @@
+ "" ""
+ SKIP=
+ }
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ # Had a bug where on extract autodetect first "switched off" -z
+ # and then failed to recognize .tgz extension
+ optional FEATURE_TAR_CREATE FEATURE_SEAMLESS_GZ
+@@ -207,7 +220,9 @@
+ " \
+ "" ""
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ # Do we detect XZ-compressed data (even w/o .tar.xz or txz extension)?
+ # (the uuencoded hello_world.txz contains one empty file named "hello_world")
+ optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_XZ
+@@ -226,7 +241,9 @@
+ ====
+ "
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ # On extract, everything up to and including last ".." component is stripped
+ optional FEATURE_TAR_CREATE
+ testing "tar strips /../ on extract" "\
+@@ -245,7 +262,9 @@
+ " \
+ "" ""
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ # attack.tar.bz2 has symlink pointing to a system file
+ # followed by a regular file with the same name
+ # containing "root::0:0::/root:/bin/sh":
+@@ -256,10 +275,11 @@
+ # The correct implementation unlinks target before
+ # creating the second file.
+ # We test that /tmp/passwd remains empty:
+-optional UUDECODE FEATURE_SEAMLESS_BZ2
++optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2
+ testing "tar does not extract into symlinks" "\
+ >>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat 
/tmp/passwd; echo \$?
+ " "\
++tar: can't create symlink 'passwd' to '/tmp/passwd'
+ 0
+ " \
+ "" "\
+@@ -271,12 +291,15 @@
+ ====
+ "
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
++
++mkdir tar.tempdir && cd tar.tempdir || exit 1
+ # And same with -k
+-optional UUDECODE FEATURE_SEAMLESS_BZ2
++optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2
+ testing "tar -k does not extract into symlinks" "\
+ >>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat 
/tmp/passwd; echo \$?
+ " "\
+-tar: can't open 'passwd': File exists
++tar: can't create symlink 'passwd' to '/tmp/passwd'
+ 0
+ " \
+ "" "\
+@@ -288,8 +311,45 @@
+ ====
+ "
+ SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
++mkdir tar.tempdir && cd tar.tempdir || exit 1
++optional UNICODE_SUPPORT FEATURE_TAR_GNU_EXTENSIONS FEATURE_SEAMLESS_BZ2 
FEATURE_TAR_AUTODETECT
++testing "Pax-encoded UTF8 names and symlinks" '\
++tar xvf ../tar.utf8.tar.bz2 2>&1; echo $?
++" \
++"" ""
++SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
+-cd .. && rm -rf tar.tempdir || exit 1
++mkdir tar.tempdir && cd tar.tempdir || exit 1
++optional FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT
++testing "Symlink attack: create symlink and then write through it" '\
++exec 2>&1
++uudecode -o input && tar xvf input; echo $?
++ls /tmp/bb_test_evilfile
++ls bb_test_evilfile
++ls symlink/bb_test_evilfile
++' "\
++anything.txt
++symlink
++symlink/bb_test_evilfile
++tar: can't create symlink 'symlink' to '/tmp'
++1
++ls: /tmp/bb_test_evilfile: No such file or directory
++ls: bb_test_evilfile: No such file or directory
++symlink/bb_test_evilfile
++" \
++"" "\
++begin-base64 644 tar_symlink_attack.tar.bz2
++QlpoOTFBWSZTWZgs7bQAALT/hMmQAFBAAf+AEMAGJPPv32AAAIAIMAC5thlR
++omAjAmCMADQT1BqNE0AEwAAjAEwElTKeo9NTR6h6gaeoA0DQNLVdwZZ5iNTk
++AQwCAV6S00QFJYhrlfFkVCEDEGtgNVqYrI0uK3ggnt30gqk4e1TTQm5QIAKa
++SJqzRGSFLMmOloHSAcvLiFxxRiQtQZF+qPxbo173ZDISOAoNoPN4PQPhBhKS
++n8fYaKlioCTzL2oXYczyUUIP4u5IpwoSEwWdtoA=
++====
++"
++SKIP=
++cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
+ 
+ exit $FAILCOUNT
diff -Nru busybox-1.22.0/debian/patches/series 
busybox-1.22.0/debian/patches/series
--- busybox-1.22.0/debian/patches/series        2015-02-17 18:29:23.000000000 
+0100
+++ busybox-1.22.0/debian/patches/series        2017-09-25 22:57:20.000000000 
+0200
@@ -27,3 +27,10 @@
 stop-checking-ancient-kernel-version.patch
 iproute-support-onelink-route-option-and-print-route-flags.patch
 update-deb-format-support.patch
+
+cherry-pick.1_22_0-220-g4e314fa.modprobe-rmmod-reject-module-names-with-slashes.patch
+cherry-pick.1_24_0-68-g1de25a6.unzip-test-for-bad-archive-segving.patch
+cherry-pick.1_24_0-139-g352f79a.udhcpc-fix-option-6rd-parsing-could-overflow-its-malloced-buffer.patch
+cherry-pick.1_24_0-152-gd474ffc.udhcp-fix-a-segv-on-malformed-rfc1035-encoded-domain-name.patch
+cherry-pick.1_24_0-44-ga960748.tar-add-a-test-that-we-dont-write-into-symlinks.patch
+cherry-pick.1_27_0-148-gb920a38.tar-postpone-creation-of-symlinks-with-suspicious-targets.patch

Attachment: signature.asc
Description: Digital signature

Reply via email to