Discussion:
Vulnerability Report: Heap-Buffer-Overflow on Sharutils (unshar) 4.15.2
(too old to reply)
nafiez
2018-02-21 07:17:55 UTC
Permalink
Hi,

Another issue found was heap-buffer-overflow on Sharutils (unshar)
4.15.2. Attached is the fuzzed file.

Below are the ASAN output:

***@fuzzing:~/sharutils-4.15.2/src$ ./unshar
out/crashes/id:000000,sig:06,src:000005+000030,op:splice,rep:4
=================================================================
==11164==ERROR: AddressSanitizer: heap-buffer-overflow on address
0xb5901100 at pc 0x0804c695 bp 0xbfe86f28 sp 0xbfe86f18
READ of size 1 at 0xb5901100 thread T0
    #0 0x804c694 in looks_like_c_code
/home/john/sharutils-4.15.2/src/unshar.c:75
    #1 0x804c694 in find_archive
/home/john/sharutils-4.15.2/src/unshar.c:253
    #2 0x804c694 in unshar_file /home/john/sharutils-4.15.2/src/unshar.c:379
    #3 0x804a2f4 in validate_fname
/home/john/sharutils-4.15.2/src/unshar-opts.c:604
    #4 0x804a2f4 in main /home/john/sharutils-4.15.2/src/unshar-opts.c:639
    #5 0xb70ab636 in __libc_start_main
(/lib/i386-linux-gnu/libc.so.6+0x18636)
    #6 0x804ab95  (/home/john/sharutils-4.15.2/src/unshar+0x804ab95)

0xb5901100 is located 0 bytes to the right of 4096-byte region
[0xb5900100,0xb5901100)
allocated by thread T0 here:
    #0 0xb72dfdee in malloc (/usr/lib/i386-linux-gnu/libasan.so.2+0x96dee)
    #1 0x804c9e4 in init_unshar /home/john/sharutils-4.15.2/src/unshar.c:450
    #2 0xb70ab636 in __libc_start_main
(/lib/i386-linux-gnu/libc.so.6+0x18636)

SUMMARY: AddressSanitizer: heap-buffer-overflow
/home/john/sharutils-4.15.2/src/unshar.c:75 looks_like_c_code
Shadow bytes around the buggy address:
  0x36b201d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x36b201e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x36b201f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x36b20200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x36b20210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x36b20220:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36b20230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36b20240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36b20250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36b20260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36b20270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3

  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==11164==ABORTING

Thanks,

Nafiez
Petr Pisar
2018-02-22 15:56:30 UTC
Permalink
The bellow patch should fix it. I don't know if sharutils author prefers
reading up to a memory page size or an I/O buffer size.
From 1067cdba6d08f2a765cb0ea371189a5b703eb4db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <***@redhat.com>
Date: Thu, 22 Feb 2018 16:39:43 +0100
Subject: [PATCH] Fix a heap-buffer-overflow in find_archive()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

rw_buffer has allocated rw_base_size bytes. But subsequend fgets() in
find_archive() reads up-to BUFSIZ bytes.

On my system, BUFSIZ is 8192. rw_base_size is usually equaled to
a memory page size, 4096 on my system. Thus find_archive() can write
beyonded allocated memmory for rw_buffer array:

$ valgrind -- ./unshar /tmp/id\:000000\,sig\:06\,src\:000005+000030\,op\:splice\,rep\:4
==30582== Memcheck, a memory error detector
==30582== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==30582== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==30582== Command: ./unshar /tmp/id:000000,sig:06,src:000005+000030,op:splice,rep:4
==30582==
==30582== Invalid write of size 1
==30582== at 0x4EAB480: _IO_getline_info (in /usr/lib64/libc-2.27.so)
==30582== by 0x4EB47C2: fgets_unlocked (in /usr/lib64/libc-2.27.so)
==30582== by 0x10BF60: fgets_unlocked (stdio2.h:320)
==30582== by 0x10BF60: find_archive (unshar.c:243)
==30582== by 0x10BF60: unshar_file (unshar.c:379)
==30582== by 0x10BCCC: validate_fname (unshar-opts.c:604)
==30582== by 0x10BCCC: main (unshar-opts.c:639)
==30582== Address 0x523a790 is 0 bytes after a block of size 4,096 alloc'd
==30582== at 0x4C2DBBB: malloc (vg_replace_malloc.c:299)
==30582== by 0x10C670: init_unshar (unshar.c:450)
==30582== by 0x10BC55: main (unshar-opts.c:630)

This was reported in
<http://lists.gnu.org/archive/html/bug-gnu-utils/2018-02/msg00004.html>.

Signed-off-by: Petr Písař <***@redhat.com>
---
src/unshar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/unshar.c b/src/unshar.c
index 80bc3a9..0fc3773 100644
--- a/src/unshar.c
+++ b/src/unshar.c
@@ -240,7 +240,7 @@ find_archive (char const * name, FILE * file, off_t start)
off_t position = ftello (file);

/* Read next line, fail if no more and no previous process. */
- if (!fgets (rw_buffer, BUFSIZ, file))
+ if (!fgets (rw_buffer, rw_base_size, file))
{
if (!start)
error (0, 0, _("Found no shell commands in %s"), name);
--
2.13.6
Loading...