Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6709 Discussions

H.264 Decoder (IPP Sample): decoder crashes when invalid prefix size in bitstream

Pascal_Binggeli
Beginner
448 Views

Hello

I'm using the H.264 decoder from audio-video-codecs, version 7.0.6.

In the method BuildNALUnit() in umc_h264_nal_spl.cpp, line 544, there is no check for the size of the input buffer in the call to memcpy. We've found an MPEG-4 clip whose prefix length is invalid for one sample in the file (generated from a Casio Digital Camera). This cause a crash since the input buffer is accessed outside of its length. Alsoa huge output buffer is allocated before the crash.

Proposal: rewrite the BuildNALUnit to take a MediaData in place of a raw buffer for the buf parameter and check that the prefix length match the buffer length before doing allocating and copying memory around.

Cheers,
Pascal

PS: Can somebody fix the incorrectly spelled "lenght"found inthe source code?
PS2: Sorry for my bad english.

0 Kudos
4 Replies
Pavel_V_Intel
Employee
447 Views
Can you upload this stream? It will be useful for reproducing and testing purposes.
>Can somebody fix the incorrectly spelled "lenght"found inthe source code?
Done )
0 Kudos
Pascal_Binggeli
Beginner
448 Views
Hello

I have attached a file as a private message.

Thanks,
Pascal
0 Kudos
Pavel_V_Intel
Employee
448 Views
Good day.
I suggest you not to use internal decoder MP4 parser (do not use AVC1_VIDEO subtype). There is MP4 splitter and it should be enough.However it requires somefixing too.
I made some changes for both of them.
MP4 splitter fix:
umc_index_spl.cpp, line 200, add buffer size check:
[cpp] pDst[0] = 0; pDst[1] = 0; pDst[2] = 1; pDst += 3; buffer_size = in.GetBufferSize() - (pDst - (Ipp8u*)in.GetBufferPointer()); if(buffer_size < NALUlen) // check nal size vs buffer size NALUlen = buffer_size; m_pReader->GetData(pDst, NALUlen);[/cpp]
BuildNALUnit fix:
umc_h264_nal_spl.h, line 132
change
[cpp]size_t BuildNALUnit(MediaDataEx * , Ipp8u * , Ipp32s lengthSize);[/cpp] to
[cpp]size_t BuildNALUnit(MediaDataEx * , Ipp8u *, size_t, Ipp32s lengthSize);[/cpp] line 179:
[cpp] friend size_t UMC::BuildNALUnit(MediaDataEx *, Ipp8u *, Ipp32s );[/cpp] to
[cpp] friend size_t UMC::BuildNALUnit(MediaDataEx *, Ipp8u *, size_t, Ipp32s );[/cpp]
umc_h264_nal_spl.cpp, line 657, add data size here:
[cpp] for (i = 0; i < avcRecord.numOfSequenceParameterSets; i++) { size_t length = BuildNALUnit(&m_MediaData, p, (pSource->GetDataSize() - (p - (Ipp8u*)pSource->GetDataPointer())), D_BYTES_FOR_HEADER_LENGHT); p += length; } avcRecord.numOfPictureParameterSets = *p; p++; // read picture par sets for (i = 0; i < avcRecord.numOfPictureParameterSets; i++) { size_t length = BuildNALUnit(&m_MediaData, p, (pSource->GetDataSize() - (p - (Ipp8u*)pSource->GetDataPointer())), D_BYTES_FOR_HEADER_LENGHT); p += length; }[/cpp] and here, line 707:
[cpp] size_t length = BuildNALUnit(&m_MediaData, (Ipp8u*)pSource->GetDataPointer(), pSource->GetDataSize(), avcRecord.lengthSizeMinusOne + 1); pSource->MoveDataPointer((Ipp32s)length);[/cpp]
and check on line 530:
[cpp] if(bufferSize < lengthSize) return 0; bufferSize -= lengthSize; size_t len = GetLenght(lengthSize, buf); if(len > bufferSize) // check nal vs buffer size len = bufferSize; buf += lengthSize;[/cpp]
0 Kudos
Pascal_Binggeli
Beginner
448 Views
Hello

Thank you very much for the time taken to look into the issue. I will try to patch my version and let you know if this fix the problem. I'm not using the IPP mp4 splitter, only the decoder.

I will keep you posted.

Pascal
0 Kudos
Reply