HLS: Ignore empty NALU to avoid error. v5.0.170

pull/3816/head
winlin 2 years ago
parent 08147f81bf
commit 939f6b484b

2
trunk/configure vendored

@ -435,7 +435,7 @@ if [[ $SRS_UTEST == YES ]]; then
MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_kernel" "srs_utest_core"
"srs_utest_config" "srs_utest_rtmp" "srs_utest_http" "srs_utest_avc" "srs_utest_reload"
"srs_utest_mp4" "srs_utest_service" "srs_utest_app" "srs_utest_rtc"
"srs_utest_protocol" "srs_utest_protocol2")
"srs_utest_protocol" "srs_utest_protocol2" "srs_utest_kernel2")
if [[ $SRS_SRT == YES ]]; then
MODULE_FILES+=("srs_utest_srt")
fi

@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v5-changes"></a>
## SRS 5.0 Changelog
* v5.0, 2023-08-02, HLS: Ignore empty NALU to avoid error. v5.0.170
* v5.0, 2023-07-26, Merge [#3699](https://github.com/ossrs/srs/pull/3699): Bugfix: Eliminate the redundant declaration of the _srs_rtc_manager variable.. v5.0.168 (#3699)
* v5.0, 2023-07-21, Merge [#3695](https://github.com/ossrs/srs/pull/3695): API: Fix HTTPS callback issue using SNI in TLS client handshake. v5.0.168 (#3695)
* v5.0, 2023-07-18, Merge [#3515](https://github.com/ossrs/srs/pull/3515): WebRTC: Support config the bitrate of transcoding AAC to Opus. v5.0.167 (#3515)

@ -9,6 +9,6 @@
#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#define VERSION_REVISION 270
#define VERSION_REVISION 271
#endif

@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 169
#define VERSION_REVISION 170
#endif

@ -599,6 +599,8 @@ srs_error_t SrsVideoFrame::add_sample(char* bytes, int size)
if ((err = SrsFrame::add_sample(bytes, size)) != srs_success) {
return srs_error_wrap(err, "add frame");
}
if (!bytes || size <= 0) return err;
// for video, parse the nalu type, set the IDR flag.
SrsAvcNaluType nal_unit_type = (SrsAvcNaluType)(bytes[0] & 0x1f);

@ -17,6 +17,9 @@
#include <string>
using namespace std;
#include <sys/types.h>
#include <sys/mman.h>
#ifdef SRS_SRT
#include <srs_app_srt_server.hpp>
#endif
@ -208,3 +211,39 @@ VOID TEST(SampleTest, ContextTest)
cache[0] = cid;
}
MockProtectedBuffer::MockProtectedBuffer() : size_(0), data_(NULL), raw_memory_(NULL)
{
}
MockProtectedBuffer::~MockProtectedBuffer()
{
if (size_ && raw_memory_) {
long page_size = sysconf(_SC_PAGESIZE);
munmap(raw_memory_, page_size * 2);
}
}
int MockProtectedBuffer::alloc(int size)
{
srs_assert(!raw_memory_);
long page_size = sysconf(_SC_PAGESIZE);
if (size >= page_size) return -1;
char* data = (char*)mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (data == MAP_FAILED) {
return -1;
}
size_ = size;
raw_memory_ = data;
data_ = data + page_size - size;
int r0 = mprotect(data + page_size, page_size, PROT_NONE);
if (r0 < 0) {
return r0;
}
return 0;
}

@ -95,5 +95,32 @@ public:
virtual ~MockEmptyLog();
};
// To test the memory corruption, we protect the memory by mprotect.
// MockProtectedBuffer buffer;
// if (buffer.alloc(8)) { EXPECT_TRUE(false); return; }
// Crash when write beyond the data:
// buffer.data_[0] = 0; // OK
// buffer.data_[7] = 0; // OK
// buffer.data_[8] = 0; // Crash
// Crash when read beyond the data:
// char v = buffer.data_[0]; // OK
// char v = buffer.data_[7]; // OK
// char v = buffer.data_[8]; // Crash
// @remark The size of memory to allocate, should smaller than page size, generally 4096 bytes.
class MockProtectedBuffer
{
private:
char* raw_memory_;
public:
int size_;
// Should use this as data.
char* data_;
public:
MockProtectedBuffer();
virtual ~MockProtectedBuffer();
// Return 0 for success.
int alloc(int size);
};
#endif

@ -411,3 +411,47 @@ VOID TEST(KernelFileWriterTest, RealfileTest)
EXPECT_STREQ("HelloWorld", str.substr(20).c_str());
}
VOID TEST(KernelCodecTest, VideoFormatSepcialMProtect_DJI_M30)
{
srs_error_t err;
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// Frame 80442, the sequence header, wireshark filter:
// rtmpt && rtmpt.video.type==1 && rtmpt.video.format==7
HELPER_EXPECT_SUCCESS(f.on_video(0, (char*)""
"\x17\x00\x00\x00\x00\x01\x64\x00\x28\xff\xe1\x00\x12\x67\x64\x00" \
"\x28\xac\xb4\x03\xc0\x11\x34\xa4\x14\x18\x18\x1b\x42\x84\xd4\x01" \
"\x00\x05\x68\xee\x06\xf2\xc0", 39));
MockProtectedBuffer buffer;
if (buffer.alloc(9)) {
EXPECT_TRUE(false) << "mmap failed, errno=" << errno;
return;
}
// Frame 82749
memcpy(buffer.data_, "\x27\x01\x00\x00\x00\x00\x00\x00\x00", buffer.size_);
HELPER_EXPECT_SUCCESS(f.on_video(0, buffer.data_, buffer.size_));
}
VOID TEST(KernelCodecTest, VideoFormatSepcialAsan_DJI_M30)
{
srs_error_t err;
SrsFormat f;
HELPER_EXPECT_SUCCESS(f.initialize());
// Frame 80442, the sequence header, wireshark filter:
// rtmpt && rtmpt.video.type==1 && rtmpt.video.format==7
HELPER_EXPECT_SUCCESS(f.on_video(0, (char*)""
"\x17\x00\x00\x00\x00\x01\x64\x00\x28\xff\xe1\x00\x12\x67\x64\x00" \
"\x28\xac\xb4\x03\xc0\x11\x34\xa4\x14\x18\x18\x1b\x42\x84\xd4\x01" \
"\x00\x05\x68\xee\x06\xf2\xc0", 39));
// Frame 82749
char data[9];
memcpy(data, "\x27\x01\x00\x00\x00\x00\x00\x00\x00", sizeof(data));
HELPER_EXPECT_SUCCESS(f.on_video(0, data, sizeof(data)));
}

Loading…
Cancel
Save