Package: dpkg
Version: 1.18.2
Severity: normal
Tags: patch

The following was reported by Jacek Wielemborek:

----- Begin forwarded message -----

Dear Maintainer,

I built dpkg with afl-gcc and AFL_USE_ASAN=1. Here's the base64-encoded
 .deb file it generated:

ITxhcmNoPopkZWJpYW4tYmluYXJ5ICAgMTQ0MTIxMTQ1NiAgMCAgICAgMCAgICAgMTAwNjQ0ICA0
ICAgICAgICAgYAoyLjAKY29udHJvbC50YXIuZ3ogIDE0NDEyMTE0NTYgIDAgICAgIDAgICAgIDEw
MDY0NCAgNDc1ICAgICAgIGAKH4sIAAAAAAACA+3RS4vbMBAAYJ/1K+bWBBK/uo6paZcWUmgpC4GE
3rXWJBarSEaSN00P/e1V/Ng+oO0ppYX5sLEsyTNjTZxEV5cGZVH0z+DnZz/O8qLMVnme9fNlmRYR
FNFf0DnPLUBkjfG/2/en9f9UnNRGe2vUlfu/urn5Vf+ztMh/7H+WPU9XEaTU/6vb8PqBH7CC9uwb
o5f4iR9bhY5tTWfrb/MC97xT3rGPaJ00uoI8LuMXy4y9sXUjPda+s2E7V4rdcal9uNFWcMe9byR3
8EEZh/BSmAfzWuC95Do29nDL3uvQAKVQLLfycwiwYmtsUQs3pYbZ7asp2XwxTob3p1K/3/Blzrah
lL7AYSfbWGms9OcKTHtZ4Iq9M0ds+79uvG+rJDmdTvGw/VJUEkpwtZXtEOcpz95Y8A3CZqhLcX3o
QhSYjYcDj8PZzBm8Hb9ZwBqPxgHXAnbGqCHIECCGXYPhTLhF2MtLAqlr1QkUYcD6TF3rvEV+nFIK
Gd7lfXcpLGYQrl0jHbRDEyEMOYj++FDX52l+AadG1s244iAEWvcdeOZgLJ1NGcZfgFndWYvaqzM8
hrOdxywihBBCCCGEEEIIIYQQQgghhBBCCCH/oK+zNHmVACgAAAo=

And here's the crash:

root@1442a2c3a089:~/fuzz/dpkg/o/crashes# dpkg --info
id\:000000\,sig\:06\,src\:000000\,op\:flip1\,pos\:7
=================================================================
==11286==ERROR: AddressSanitizer: stack-buffer-overflow on address
0x7fffbdcdf338 at pc 0x00000040cf49 bp 0x7fffbdcdef70 sp 0x7fffbdcdef68
WRITE of size 1 at 0x7fffbdcdf338 thread T0
    #0 0x40cf48  (/usr/bin/dpkg-deb+0x40cf48)
    #1 0x410dfe  (/usr/bin/dpkg-deb+0x410dfe)
    #2 0x4056e2  (/usr/bin/dpkg-deb+0x4056e2)
    #3 0x7f38390b8b44 in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
    #4 0x4074ca  (/usr/bin/dpkg-deb+0x4074ca)

Address 0x7fffbdcdf338 is located in stack of thread T0 at offset 872 in
frame
    #0 0x40b4bf  (/usr/bin/dpkg-deb+0x40b4bf)

  This frame has 13 object(s):
    [32, 33) 'nlc'
    [96, 100) 'dummy'
    [160, 168) 'version'
    [224, 232) 'ctrllennum'
    [288, 304) 'err'
    [352, 384) 'cmd'
    [416, 424) 'p1'
    [480, 488) 'p2'
    [544, 604) 'arh'
    [640, 784) 'stab'
    [832, 872) 'versionbuf' <== Memory access at offset 872 overflows
this variable
    [928, 968) 'ctrllenbuf'
    [1024, 1224) 'buf'
HINT: this may be a false positive if your program uses some custom
stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 ??
Shadow bytes around the buggy address:
  0x100077b93e10: f4 f4 f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 00
  0x100077b93e20: f4 f4 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 f4
  0x100077b93e30: f4 f4 f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 00
  0x100077b93e40: 00 00 00 00 00 04 f2 f2 f2 f2 00 00 00 00 00 00
  0x100077b93e50: 00 00 00 00 00 00 00 00 00 00 00 00 f4 f4 f2 f2
=>0x100077b93e60: f2 f2 00 00 00 00 00[f4]f4 f4 f2 f2 f2 f2 00 00
  0x100077b93e70: 00 00 00 f4 f4 f4 f2 f2 f2 f2 00 00 00 00 00 00
  0x100077b93e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100077b93e90: 00 00 00 f4 f4 f4 f3 f3 f3 f3 00 00 00 00 00 00
  0x100077b93ea0: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00
  0x100077b93eb0: f4 f4 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
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
==11286==ABORTING

To be on the safe side, I'm reporting it as a critical security vuln
because this is a memory error in the core component. Please contact me
on d33...@gmail.com.

----- End forwarded message -----

Quoting Guillem:

> The .deb is an ar archive w/o the '\n' trailer on the «!<arch>» magic
> value. The dpkg-deb/extract.c:extracthalf() function calls read_line()
> passing to it versionbuf with the off-by-one length, that one writes
> 41 bytes into it (with a trailing \0), stomping on whatever is next in
> the stack. But this should in principle have no visible effect because
> regardless of how the compiler has organized the local stack, any
> subsequently used local variable is first assigned so the trailing \0
> would not be in effect, and versionbuf is only ever used to compare
> against shorter constant strings, which should all fail, the first
> against "!<arch>\n", then against "0.93", and after that it just
> aborts the program.

Attached is the corresponding patch.

Regards,
Salvatore
>From ac3ee4c3db5ecca5d2c343415273823da4c107ae Mon Sep 17 00:00:00 2001
From: Guillem Jover <guil...@debian.org>
Date: Sun, 6 Sep 2015 21:25:00 +0200
Subject: [PATCH] dpkg-deb: Fix off-by-one write access on versionbuf variable

Reported-by: Jacek Wielemborek <d33...@gmail.com>
---
 dpkg-deb/extract.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c
index d5ac05c..1d2a76a 100644
--- a/dpkg-deb/extract.c
+++ b/dpkg-deb/extract.c
@@ -131,7 +131,7 @@ extracthalf(const char *debar, const char *dir,
   if (fstat(arfd, &stab))
     ohshite(_("failed to fstat archive"));
 
-  r = read_line(arfd, versionbuf, strlen(DPKG_AR_MAGIC), sizeof(versionbuf));
+  r = read_line(arfd, versionbuf, strlen(DPKG_AR_MAGIC), sizeof(versionbuf) - 1);
   if (r < 0)
     read_fail(r, debar, _("archive magic version number"));
 
-- 
2.5.1

Reply via email to