justdan96 / tsMuxer

tsMuxer is a transport stream muxer for remuxing/muxing elementary streams, EVO/VOB/MPG, MKV/MKA, MP4/MOV, TS, M2TS to TS to M2TS. Supported video codecs H.264/AVC, H.265/HEVC, VC-1, MPEG2. Supported audio codecs AAC, AC3 / E-AC3(DD+), DTS/ DTS-HD.
Apache License 2.0
829 stars 140 forks source link

stack buffer over-read is found in TS_program_map_section::extractPMTDescriptors #859

Closed iwashiira closed 3 months ago

iwashiira commented 3 months ago

Our fuzzer found stack buffer over-read in tsDemuxer. in the current master(75c9cb3). PoC is here.

#include "bufferedReaderManager.h"
#include "vod_common.h"
#include "abstractDemuxer.h"
#include "tsDemuxer.h"
#include <cstdint>
#include <fs/systemlog.h>

using namespace std;

BufferedReaderManager readManager(2, DEFAULT_FILE_BLOCK_SIZE, DEFAULT_FILE_BLOCK_SIZE + MAX_AV_PACKET_SIZE,
                                  DEFAULT_FILE_BLOCK_SIZE / 2);

int main(int argc, char* argv[]) {
    string fileName = argv[1];
    AbstractDemuxer* demuxer = new TSDemuxer(readManager, "");

    uint32_t fileBlockSize = demuxer->getFileBlockSize();
    demuxer->openFile(fileName);
    int64_t discardedSize = 0;
    DemuxedData demuxedData;
    map<int32_t, TrackInfo> acceptedPidMap;
    demuxer->getTrackList(acceptedPidMap);

    return 0;
}

Folloing is an output of ASAN. vuln22.ts is in poc22.zip

$ tsmuxer ./crash/vuln22.ts
=================================================================
==12233==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe15ac2cf0 at pc 0x5561b76681bb bp 0x7ffe15ac1360 sp 0x7ffe15ac1350
READ of size 1 at 0x7ffe15ac2cf0 thread T0
    #0 0x5561b76681ba in TS_program_map_section::extractPMTDescriptors(unsigned char*, int) (/home/vagrant/tsmuxer/for_build/build/tsMuxer/tsmuxer+0x52b1ba)
    #1 0x5561b7668833 in TS_program_map_section::deserialize(unsigned char*, int) (/home/vagrant/tsmuxer/for_build/build/tsMuxer/tsmuxer+0x52b833)
    #2 0x5561b76295de in TSDemuxer::getTrackList(std::map<int, TrackInfo, std::less<int>, std::allocator<std::pair<int const, TrackInfo> > >&) (/home/vagrant/tsmuxer/for_build/build/tsMuxer/tsmuxer+0x4ec5de)
    #3 0x5561b749ff4b in main (/home/vagrant/tsmuxer/for_build/build/tsMuxer/tsmuxer+0x362f4b)
    #4 0x7f7a7eed7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #5 0x7f7a7eed7e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #6 0x5561b73b50d4 in _start (/home/vagrant/tsmuxer/for_build/build/tsMuxer/tsmuxer+0x2780d4)

Address 0x7ffe15ac2cf0 is located in stack of thread T0 at offset 5696 in frame
    #0 0x5561b7628aef in TSDemuxer::getTrackList(std::map<int, TrackInfo, std::less<int>, std::allocator<std::pair<int const, TrackInfo> > >&) (/home/vagrant/tsmuxer/for_build/build/tsMuxer/tsmuxer+0x4ebaef)

  This frame has 16 object(s):
    [48, 52) 'readedBytes' (line 61)
    [64, 68) 'lastReadRez' (line 68)
    [80, 84) 'pid' (line 104)
    [96, 104) '<unknown>'
    [128, 136) '<unknown>'
    [160, 168) '__for_begin' (line 128)
    [192, 200) '__for_end' (line 128)
    [224, 272) 'nonProcPMTPid' (line 65)
    [304, 360) 'pat' (line 84)
    [400, 432) '<unknown>'
    [464, 496) '<unknown>'
    [528, 576) '<unknown>'
    [608, 664) '<unknown>'
    [704, 1080) 'ss' (line 138)
    [1152, 1528) 'ss' (line 156)
    [1600, 5696) 'pmtBuffer' (line 58) <== Memory access at offset 5696 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/vagrant/tsmuxer/for_build/build/tsMuxer/tsmuxer+0x52b1ba) in TS_program_map_section::extractPMTDescriptors(unsigned char*, int)
Shadow bytes around the buggy address:
  0x100042b50540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100042b50550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100042b50560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100042b50570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100042b50580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100042b50590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[f3]f3
  0x100042b505a0: f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 f3 00 00
  0x100042b505b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100042b505c0: f1 f1 f1 f1 f1 f1 f8 f2 00 00 00 00 00 00 f2 f2
  0x100042b505d0: f2 f2 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00 00
  0x100042b505e0: f3 f3 f3 f3 00 00 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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  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
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==12233==ABORTING

It is caused by these line. https://github.com/justdan96/tsMuxer/blob/5f43ab2a45482ad448524dc61a1ab7204ca8849d/tsMuxer/tsPacket.cpp#L293-L295

Ricerca Security, Inc.