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
heap buffer over-read is found in getLastPCR (programStreamDemuxer.cpp) #836
Folloing is an output of valgrind.
vuln17.vob is in poc17.zip
==25736== Memcheck, a memory error detector
==25736== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25736== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==25736== Command: ../tsMuxer/build/tsMuxer/tsmuxer ./crash/vuln17.vob
==25736==
==25736== Warning: invalid file descriptor -1 in syscall close()
==25736== Invalid read of size 1
==25736== at 0x360170: get_pts(unsigned char const*) (pesPacket.h:13)
==25736== by 0x362359: PESPacket::getPts() (pesPacket.h:162)
==25736== by 0x361E25: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:367)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736== Address 0x5184140 is 0 bytes after a block of size 262,144 alloc'd
==25736== at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==25736== by 0x361D73: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:350)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736==
==25736== Invalid read of size 1
==25736== at 0x360198: get_pts(unsigned char const*) (pesPacket.h:14)
==25736== by 0x362359: PESPacket::getPts() (pesPacket.h:162)
==25736== by 0x361E25: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:367)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736== Address 0x5184141 is 1 bytes after a block of size 262,144 alloc'd
==25736== at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==25736== by 0x361D73: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:350)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736==
==25736== Invalid read of size 1
==25736== at 0x3601AB: get_pts(unsigned char const*) (pesPacket.h:14)
==25736== by 0x362359: PESPacket::getPts() (pesPacket.h:162)
==25736== by 0x361E25: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:367)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736== Address 0x5184142 is 2 bytes after a block of size 262,144 alloc'd
==25736== at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==25736== by 0x361D73: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:350)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736==
==25736== Invalid read of size 1
==25736== at 0x3601CC: get_pts(unsigned char const*) (pesPacket.h:16)
==25736== by 0x362359: PESPacket::getPts() (pesPacket.h:162)
==25736== by 0x361E25: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:367)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736== Address 0x5184143 is 3 bytes after a block of size 262,144 alloc'd
==25736== at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==25736== by 0x361D73: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:350)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736==
==25736== Invalid read of size 1
==25736== at 0x3601DF: get_pts(unsigned char const*) (pesPacket.h:16)
==25736== by 0x362359: PESPacket::getPts() (pesPacket.h:162)
==25736== by 0x361E25: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:367)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736== Address 0x5184144 is 4 bytes after a block of size 262,144 alloc'd
==25736== at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==25736== by 0x361D73: getLastPCR(File const&, int, long) (programStreamDemuxer.cpp:350)
==25736== by 0x362034: getPSDuration(char const*) (programStreamDemuxer.cpp:422)
==25736== by 0x3620FD: ProgramStreamDemuxer::getFileDurationNano() const (programStreamDemuxer.cpp:438)
==25736== by 0x2E688D: main (main.cpp:25)
==25736==
==25736==
==25736== HEAP SUMMARY:
==25736== in use at exit: 2,047 bytes in 2 blocks
==25736== total heap usage: 265 allocs, 263 frees, 4,896,926 bytes allocated
==25736==
==25736== LEAK SUMMARY:
==25736== definitely lost: 2,016 bytes in 1 blocks
==25736== indirectly lost: 31 bytes in 1 blocks
==25736== possibly lost: 0 bytes in 0 blocks
==25736== still reachable: 0 bytes in 0 blocks
==25736== suppressed: 0 bytes in 0 blocks
==25736== Rerun with --leak-check=full to see details of leaked memory
==25736==
==25736== For lists of detected and suppressed errors, rerun with: -s
==25736== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
The internal function get_pts(), which is executed in getPts(), considers the area beyond CurPos+9 to be the 8-byte area where pts are stored and reads 8 bytes, which causes OOB (heap buffer over-read).
Our fuzzer found heap buffer over-read in programStreamDemuxer. in the current master(75c9cb3). PoC is here.
Folloing is an output of valgrind. vuln17.vob is in poc17.zip
It is caused by this line. https://github.com/justdan96/tsMuxer/blob/75c9cb3514815d07378007d36cc90c3f209e7b36/tsMuxer/programStreamDemuxer.cpp#L359
The internal function get_pts(), which is executed in getPts(), considers the area beyond CurPos+9 to be the 8-byte area where pts are stored and reads 8 bytes, which causes OOB (heap buffer over-read).
https://github.com/justdan96/tsMuxer/blob/75c9cb3514815d07378007d36cc90c3f209e7b36/tsMuxer/programStreamDemuxer.cpp#L367
Ricerca Security, Inc.