Menu

#183 heap out of bounds read in NArchive::N7z::CDecoder::Decode on malformed input

v1.0 (example)
closed-fixed
nobody
16.02 (1)
5
2016-07-30
2016-06-24
Hanno Böck
No

The attached file causes an out of bounds heap read access. You may want to treat this as a security issue.
This issue can only be seen with memory check tools like address sanitizer (by adding -fsanitize=address to the cflags).

Here's the asan error message from a debug build:

==24000==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000009d38 at pc 0x482d10 bp 0x7ffce1f487b0 sp 0x7ffce1f487a0
READ of size 8 at 0x602000009d38 thread T0
    #0 0x482d0f in NArchive::N7z::CDecoder::Decode(IInStream*, unsigned long long, NArchive::N7z::CFolders const&, unsigned int, unsigned long long const*, ISequentialOutStream*, ICompressProgressInfo*, ISequentialInStream**, ICryptoGetTextPassword*, bool&, bool&, UString&, bool, unsigned int) ../../../../CPP/7zip/Archive/7z/7zDecode.cpp:443
    #1 0x4ae30f in NArchive::N7z::CInArchive::ReadAndDecodePackedStreams(unsigned long long, unsigned long long&, CObjectVector<CBuffer<unsigned char> >&, ICryptoGetTextPassword*, bool&, bool&, UString&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:1087
    #2 0x4b1275 in NArchive::N7z::CInArchive::ReadDatabase2(NArchive::N7z::CDbEx&, ICryptoGetTextPassword*, bool&, bool&, UString&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:1579
    #3 0x4b1684 in NArchive::N7z::CInArchive::ReadDatabase(NArchive::N7z::CDbEx&, ICryptoGetTextPassword*, bool&, bool&, UString&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:1613
    #4 0x49e07f in NArchive::N7z::CHandler::Open(IInStream*, unsigned long long const*, IArchiveOpenCallback*) ../../../../CPP/7zip/Archive/7z/7zHandler.cpp:676
    #5 0x605c45 in OpenArchiveSpec ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:1537
    #6 0x60bd31 in CArc::OpenStream2(COpenOptions const&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:2604
    #7 0x60d3bb in CArc::OpenStream(COpenOptions const&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:2867
    #8 0x60dd12 in CArc::OpenStreamOrFile(COpenOptions&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:2959
    #9 0x60e814 in CArchiveLink::Open(COpenOptions&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:3135
    #10 0x60f933 in CArchiveLink::Open2(COpenOptions&, IOpenCallbackUI*) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:3258
    #11 0x6103c2 in CArchiveLink::Open3(COpenOptions&, IOpenCallbackUI*) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:3322
    #12 0x63e70e in ListArchives(CCodecs*, CObjectVector<COpenType> const&, CRecordVector<int> const&, bool, CObjectVector<UString>&, CObjectVector<UString>&, bool, bool, NWildcard::CCensorNode const&, bool, bool, bool&, UString&, CObjectVector<CProperty> const*, unsigned long long&, unsigned long long&) ../../../../CPP/7zip/UI/Console/List.cpp:1075
    #13 0x6446fe in Main2(int, char**) ../../../../CPP/7zip/UI/Console/Main.cpp:1054
    #14 0x648ba0 in main ../../../../CPP/7zip/UI/Console/MainAr.cpp:70
    #15 0x7f3ba63c378f in __libc_start_main (/lib64/libc.so.6+0x2078f)
    #16 0x4036e8 in _start (/mnt/ram/7z/7za-debug+0x4036e8)

0x602000009d38 is located 0 bytes to the right of 8-byte region [0x602000009d30,0x602000009d38)
allocated by thread T0 here:
    #0 0x7f3ba72491cf in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libasan.so.1+0x581cf)
    #1 0x4b242b in CObjArray<unsigned long long>::Alloc(unsigned long) ../../../../CPP/7zip/Archive/7z/../../Common/../../Common/MyBuffer.h:152
    #2 0x4ab61f in NArchive::N7z::CInArchive::ReadPackInfo(NArchive::N7z::CFolders&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:590
    #3 0x4ad918 in NArchive::N7z::CInArchive::ReadStreamsInfo(CObjectVector<CBuffer<unsigned char> > const*, unsigned long long&, NArchive::N7z::CFolders&, CRecordVector<unsigned long long>&, NArchive::N7z::CUInt32DefVector&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:946
    #4 0x4ae115 in NArchive::N7z::CInArchive::ReadAndDecodePackedStreams(unsigned long long, unsigned long long&, CObjectVector<CBuffer<unsigned char> >&, ICryptoGetTextPassword*, bool&, bool&, UString&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:1055
    #5 0x4b1275 in NArchive::N7z::CInArchive::ReadDatabase2(NArchive::N7z::CDbEx&, ICryptoGetTextPassword*, bool&, bool&, UString&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:1579
    #6 0x4b1684 in NArchive::N7z::CInArchive::ReadDatabase(NArchive::N7z::CDbEx&, ICryptoGetTextPassword*, bool&, bool&, UString&) ../../../../CPP/7zip/Archive/7z/7zIn.cpp:1613
    #7 0x49e07f in NArchive::N7z::CHandler::Open(IInStream*, unsigned long long const*, IArchiveOpenCallback*) ../../../../CPP/7zip/Archive/7z/7zHandler.cpp:676
    #8 0x605c45 in OpenArchiveSpec ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:1537
    #9 0x60bd31 in CArc::OpenStream2(COpenOptions const&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:2604
    #10 0x60d3bb in CArc::OpenStream(COpenOptions const&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:2867
    #11 0x60dd12 in CArc::OpenStreamOrFile(COpenOptions&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:2959
    #12 0x60e814 in CArchiveLink::Open(COpenOptions&) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:3135
    #13 0x60f933 in CArchiveLink::Open2(COpenOptions&, IOpenCallbackUI*) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:3258
    #14 0x6103c2 in CArchiveLink::Open3(COpenOptions&, IOpenCallbackUI*) ../../../../CPP/7zip/UI/Common/OpenArchive.cpp:3322
    #15 0x63e70e in ListArchives(CCodecs*, CObjectVector<COpenType> const&, CRecordVector<int> const&, bool, CObjectVector<UString>&, CObjectVector<UString>&, bool, bool, NWildcard::CCensorNode const&, bool, bool, bool&, UString&, CObjectVector<CProperty> const*, unsigned long long&, unsigned long long&) ../../../../CPP/7zip/UI/Console/List.cpp:1075
    #16 0x6446fe in Main2(int, char**) ../../../../CPP/7zip/UI/Console/Main.cpp:1054
    #17 0x648ba0 in main ../../../../CPP/7zip/UI/Console/MainAr.cpp:70
    #18 0x7f3ba63c378f in __libc_start_main (/lib64/libc.so.6+0x2078f)

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../CPP/7zip/Archive/7z/7zDecode.cpp:443 NArchive::N7z::CDecoder::Decode(IInStream*, unsigned long long, NArchive::N7z::CFolders const&, unsigned int, unsigned long long const*, ISequentialOutStream*, ICompressProgressInfo*, ISequentialInStream**, ICryptoGetTextPassword*, bool&, bool&, UString&, bool, unsigned int)
Shadow bytes around the buggy address:
  0x0c047fff9350: fa fa fd fa fa fa 04 fa fa fa 04 fa fa fa 04 fa
  0x0c047fff9360: fa fa 00 fa fa fa 04 fa fa fa 04 fa fa fa 05 fa
  0x0c047fff9370: fa fa 00 fa fa fa 00 00 fa fa 00 fa fa fa 04 fa
  0x0c047fff9380: fa fa 04 fa fa fa 01 fa fa fa 00 fa fa fa 00 03
  0x0c047fff9390: fa fa 00 fa fa fa 00 fa fa fa 00 00 fa fa 01 fa
=>0x0c047fff93a0: fa fa 00 fa fa fa 00[fa]fa fa 00 00 fa fa 00 00
  0x0c047fff93b0: fa fa 04 fa fa fa 00 00 fa fa fd fd fa fa fd fa
  0x0c047fff93c0: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c047fff93d0: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c047fff93e0: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c047fff93f0: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd 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
  Contiguous container OOB:fc
  ASan internal:           fe
==24000==ABORTING
1 Attachments

Discussion

  • Igor Pavlov

    Igor Pavlov - 2016-06-25

    It was fixed in 7-zip code already.
    Waiting for p7zip release.

     
  • my p7zip

    my p7zip - 2016-07-14
    • labels: --> 16.02
    • status: open --> closed-fixed
     
  • my p7zip

    my p7zip - 2016-07-14

    Please, try p7zip 16.02

     
  • Hanno Böck

    Hanno Böck - 2016-07-15

    Can confirm fix. I think this bug report can now go public, can you change the "Private" flag? I don't have the permission to change it.

     
  • my p7zip

    my p7zip - 2016-07-30
    • private: Yes --> No
     

Log in to post a comment.

MongoDB Logo MongoDB