[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-cpio] cpio: reads out-of-bounds with cpio 2.11
From: |
Petter Reinholdtsen |
Subject: |
Re: [Bug-cpio] cpio: reads out-of-bounds with cpio 2.11 |
Date: |
Tue, 14 Jun 2016 01:16:30 +0200 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
Control: forwarded -1
http://lists.gnu.org/archive/html/bug-cpio/2015-09/msg00002.html
Control: tags -1 + patch
[Salvatore Bonaccorso]
> See http://seclists.org/oss-sec/2016/q1/440 for reproducers (isses can
> be uncovered if compiled with ASAN). There is no CVE assigned yet for
> those, and as well I think no patch from upstream.
I tested with 2.11+dfsg-4.1+deb8u1 and the problematic input file provided from
<URL: http://seclists.org/oss-sec/2016/q1/att-440/overflow_cpio.bin >, and
the problem exist.
I notice there is a new upstream version 2.12 available. The problem seem to
exist also there:
% valgrind ./src/cpio -i < ../cpio-2.11+dfsg/overflow_cpio.bin
==27368== Memcheck, a memory error detector
==27368== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==27368== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==27368== Command: ./src/cpio -i
==27368==
./src/cpio: warning: skipped 8 bytes of junk
==27368== Invalid read of size 1
==27368== at 0x4041B3: process_copy_in (copyin.c:1382)
==27368== by 0x402AA0: main (main.c:788)
==27368== Address 0x51e52a0 is 0 bytes after a block of size 0 alloc'd
==27368== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==27368== by 0x416818: xmalloc (xmalloc.c:41)
==27368== by 0x403987: read_in_new_ascii (copyin.c:1161)
==27368== by 0x403D87: read_in_header (copyin.c:1038)
==27368== by 0x40419F: process_copy_in (copyin.c:1358)
==27368== by 0x402AA0: main (main.c:788)
==27368==
==27368== Invalid read of size 1
==27368== at 0x40E07C: safer_name_suffix (names.c:148)
==27368== by 0x40B4D5: cpio_safer_name_suffix (util.c:1419)
==27368== by 0x4041D3: process_copy_in (copyin.c:1388)
==27368== by 0x402AA0: main (main.c:788)
==27368== Address 0x51e52a0 is 0 bytes after a block of size 0 alloc'd
==27368== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==27368== by 0x416818: xmalloc (xmalloc.c:41)
==27368== by 0x403987: read_in_new_ascii (copyin.c:1161)
==27368== by 0x403D87: read_in_header (copyin.c:1038)
==27368== by 0x40419F: process_copy_in (copyin.c:1358)
==27368== by 0x402AA0: main (main.c:788)
==27368==
./src/cpio: Substituting `.' for empty member name
==27368== Invalid write of size 1
==27368== at 0x4C2D6A3: address@hidden (vg_replace_strmem.c:914)
==27368== by 0x4041D3: process_copy_in (copyin.c:1388)
==27368== by 0x402AA0: main (main.c:788)
==27368== Address 0x51e52a0 is 0 bytes after a block of size 0 alloc'd
==27368== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==27368== by 0x416818: xmalloc (xmalloc.c:41)
==27368== by 0x403987: read_in_new_ascii (copyin.c:1161)
==27368== by 0x403D87: read_in_header (copyin.c:1038)
==27368== by 0x40419F: process_copy_in (copyin.c:1358)
==27368== by 0x402AA0: main (main.c:788)
==27368==
==27368== Syscall param lstat(file_name) points to unaddressable byte(s)
==27368== at 0x4F10805: _lxstat (lxstat.c:35)
==27368== by 0x404775: lstat (stat.h:462)
==27368== by 0x404775: try_existing_file (copyin.c:209)
==27368== by 0x404775: copyin_file (copyin.c:704)
==27368== by 0x404775: process_copy_in (copyin.c:1482)
==27368== by 0x402AA0: main (main.c:788)
==27368== Address 0x51e52a0 is 0 bytes after a block of size 0 alloc'd
==27368== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==27368== by 0x416818: xmalloc (xmalloc.c:41)
==27368== by 0x403987: read_in_new_ascii (copyin.c:1161)
==27368== by 0x403D87: read_in_header (copyin.c:1038)
==27368== by 0x40419F: process_copy_in (copyin.c:1358)
==27368== by 0x402AA0: main (main.c:788)
==27368==
./src/cpio: ==27368== Invalid read of size 1
==27368== at 0x4E7FDCC: vfprintf (vfprintf.c:1642)
==27368== by 0x4E80B00: buffered_vfprintf (vfprintf.c:2348)
==27368== by 0x4E7B37D: vfprintf (vfprintf.c:1296)
==27368== by 0x4F1BAE5: error_tail (error.c:196)
==27368== by 0x4F1BC3D: error (error.c:246)
==27368== by 0x404C25: try_existing_file (copyin.c:233)
==27368== by 0x404C25: copyin_file (copyin.c:704)
==27368== by 0x404C25: process_copy_in (copyin.c:1482)
==27368== by 0x402AA0: main (main.c:788)
==27368== Address 0x51e52a0 is 0 bytes after a block of size 0 alloc'd
==27368== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==27368== by 0x416818: xmalloc (xmalloc.c:41)
==27368== by 0x403987: read_in_new_ascii (copyin.c:1161)
==27368== by 0x403D87: read_in_header (copyin.c:1038)
==27368== by 0x40419F: process_copy_in (copyin.c:1358)
==27368== by 0x402AA0: main (main.c:788)
==27368==
==27368== Invalid read of size 1
==27368== at 0x4EAB240: _IO_default_xsputn (genops.c:475)
==27368== by 0x4E7FD86: vfprintf (vfprintf.c:1642)
==27368== by 0x4E80B00: buffered_vfprintf (vfprintf.c:2348)
==27368== by 0x4E7B37D: vfprintf (vfprintf.c:1296)
==27368== by 0x4F1BAE5: error_tail (error.c:196)
==27368== by 0x4F1BC3D: error (error.c:246)
==27368== by 0x404C25: try_existing_file (copyin.c:233)
==27368== by 0x404C25: copyin_file (copyin.c:704)
==27368== by 0x404C25: process_copy_in (copyin.c:1482)
==27368== by 0x402AA0: main (main.c:788)
==27368== Address 0x51e52a0 is 0 bytes after a block of size 0 alloc'd
==27368== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==27368== by 0x416818: xmalloc (xmalloc.c:41)
==27368== by 0x403987: read_in_new_ascii (copyin.c:1161)
==27368== by 0x403D87: read_in_header (copyin.c:1038)
==27368== by 0x40419F: process_copy_in (copyin.c:1358)
==27368== by 0x402AA0: main (main.c:788)
==27368==
. not created: newer or same age version exists
./src/cpio: premature end of file
==27368==
==27368== HEAP SUMMARY:
==27368== in use at exit: 1,536 bytes in 3 blocks
==27368== total heap usage: 66 allocs, 63 frees, 17,291 bytes allocated
==27368==
==27368== LEAK SUMMARY:
==27368== definitely lost: 0 bytes in 0 blocks
==27368== indirectly lost: 0 bytes in 0 blocks
==27368== possibly lost: 0 bytes in 0 blocks
==27368== still reachable: 1,536 bytes in 3 blocks
==27368== suppressed: 0 bytes in 0 blocks
==27368== Rerun with --leak-check=full to see details of leaked memory
==27368==
==27368== For counts of detected and suppressed errors, rerun with: -v
==27368== ERROR SUMMARY: 8 errors from 6 contexts (suppressed: 0 from 0)
%
The problem was reported upstream, but the response seem to fail to understand
the problem, as far as I can tell from
<URL: http://lists.gnu.org/archive/html/bug-cpio/2015-09/msg00003.html >.
I had a look at the code, and suspect the easy way to handle this is to reject
files with zero length names using this patch:
--- cpio-2.11+dfsg.orig/src/copyin.c
+++ cpio-2.11+dfsg/src/copyin.c
@@ -1204,6 +1204,12 @@ read_in_new_ascii (struct cpio_file_stat
file_hdr->c_rdev_min = FROM_HEX (ascii_header.c_rdev_min);
file_hdr->c_namesize = FROM_HEX (ascii_header.c_namesize);
file_hdr->c_chksum = FROM_HEX (ascii_header.c_chksum);
+
+ /* Reject bogus input name */
+ if (0 >= file_hdr->c_namesize)
+ {
+ error (PAXEXIT_FAILURE, 0, _("zero length name size"));
+ }
/* Read file name from input. */
if (file_hdr->c_name != NULL)
I tried first by replacing xmalloc(0) with xmalloc(1) and a
'ptr[len-1] = 0' line, but this still caused out of bounds writes.
--
Happy hacking
Petter Reinholdtsen
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Bug-cpio] cpio: reads out-of-bounds with cpio 2.11,
Petter Reinholdtsen <=