mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-28 13:04:07 +08:00
fix: harden AAC RTP decoder payload bounds checks (#4788)
### Motivation - 修复 `ext-codec/AACRtp.cpp` 中的越界读取问题,避免在处理异常短的 AAC RTP payload 时读取 `ptr[1]` 导致堆越界(CWE-125)。 - 在解码器层对输入数据做前置且严格的长度校验以防止网络可达的、未认证或畸形的 RTP 包触发服务可用性影响。 ### Description - 在 `AACRtpDecoder::inputRtp` 中对 `payload_size` 强制要求至少为 2 字节以保障对 AU-Header-Length 的安全读取。 - 添加对 AU-header 表的完整性检查:计算 `au_headers_size = au_header_count * 2` 并在访问 AU-header 或做指针偏移前验证可用字节,否则拒绝该包。 - 在 `flushData()` 中将帧长度判断移到前面,先检查 `_frame->size() > ADTS_HEADER_LEN` 再访问 `ptr[0]`/`ptr[1]`,避免短帧情况下的顺序求值导致的越界读取。 ### Testing - 运行 `git diff --check`,无格式/冲突检查错误并通过。 - 运行配置命令 `cmake -S . -B build -DENABLE_TESTS=OFF -DENABLE_WEBRTC=OFF -DENABLE_SRT=OFF -DENABLE_FFMPEG=OFF -DCMAKE_BUILD_TYPE=Debug`,CMake 配置成功。 - 运行构建 `cmake --build build --target zlmediakit -j2`,目标构建完成且 `zlmediakit` 目标成功编译。 ------ [Codex Task](https://chatgpt.com/codex/cloud/tasks/task_e_6a63e2a088ac8320ac3864716f13c995)
This commit is contained in:
@@ -55,9 +55,9 @@ void AACRtpDecoder::obtainFrame() {
|
|||||||
|
|
||||||
bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
||||||
auto payload_size = rtp->getPayloadSize();
|
auto payload_size = rtp->getPayloadSize();
|
||||||
if (payload_size <= 0) {
|
if (payload_size < 2) {
|
||||||
// 无实际负载 [AUTO-TRANSLATED:2267e6ac]
|
// AU-Header-Length至少占用两个字节 [AUTO-TRANSLATED:2267e6ac]
|
||||||
// No actual load
|
// AU-Header-Length occupies at least two bytes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,16 +77,16 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
|||||||
WarnL << "invalid aac rtp au_header_count";
|
WarnL << "invalid aac rtp au_header_count";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
auto au_headers_size = static_cast<size_t>(au_header_count) * 2;
|
||||||
|
if (static_cast<size_t>(payload_size) - 2 < au_headers_size) {
|
||||||
|
// AU-Header数据不完整 [AUTO-TRANSLATED:830a2785]
|
||||||
|
// Incomplete AU-Header data
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// 记录au_header起始指针 [AUTO-TRANSLATED:b9083b72]
|
// 记录au_header起始指针 [AUTO-TRANSLATED:b9083b72]
|
||||||
// Record the starting pointer of au_header
|
// Record the starting pointer of au_header
|
||||||
auto au_header_ptr = ptr + 2;
|
auto au_header_ptr = ptr + 2;
|
||||||
ptr = au_header_ptr + au_header_count * 2;
|
ptr = au_header_ptr + au_headers_size;
|
||||||
|
|
||||||
if (end < ptr) {
|
|
||||||
// 数据不够 [AUTO-TRANSLATED:830a2785]
|
|
||||||
// Not enough data
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_last_dts) {
|
if (!_last_dts) {
|
||||||
// 记录第一个时间戳 [AUTO-TRANSLATED:2e85b398]
|
// 记录第一个时间戳 [AUTO-TRANSLATED:2e85b398]
|
||||||
@@ -130,7 +130,7 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
|||||||
|
|
||||||
void AACRtpDecoder::flushData() {
|
void AACRtpDecoder::flushData() {
|
||||||
auto ptr = reinterpret_cast<const uint8_t *>(_frame->data());
|
auto ptr = reinterpret_cast<const uint8_t *>(_frame->data());
|
||||||
if ((ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0) && _frame->size() > ADTS_HEADER_LEN) {
|
if (_frame->size() > ADTS_HEADER_LEN && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0) {
|
||||||
// adts头打入了rtp包,不符合规范,兼容EasyPusher的bug [AUTO-TRANSLATED:203a5ee9]
|
// adts头打入了rtp包,不符合规范,兼容EasyPusher的bug [AUTO-TRANSLATED:203a5ee9]
|
||||||
// The adts header is inserted into the rtp packet, which is not compliant with the specification, compatible with the bug of EasyPusher
|
// The adts header is inserted into the rtp packet, which is not compliant with the specification, compatible with the bug of EasyPusher
|
||||||
_frame->_prefix_size = ADTS_HEADER_LEN;
|
_frame->_prefix_size = ADTS_HEADER_LEN;
|
||||||
@@ -139,4 +139,4 @@ void AACRtpDecoder::flushData() {
|
|||||||
obtainFrame();
|
obtainFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
|||||||
Reference in New Issue
Block a user