Commit d7ec45ab for openh264
commit d7ec45ab1fe4590473968004e38fe76257b7c4c4
Author: BenzhengZhang <140143892+BenzhengZhang@users.noreply.github.com>
Date: Fri Aug 28 15:50:55 2026 +0800
decoder: validate GMP BufferLength32 lengths before rewrite (#3971)
* decoder: validate GMP BufferLength32 lengths before rewrite
* decoder: harden GMP_BufferLength32 rewrite bounds
---------
Co-authored-by: benzzhan <benzzhan@cisco.com>
diff --git a/module/gmp-openh264.cpp b/module/gmp-openh264.cpp
index 4380c9c9..6354f315 100644
--- a/module/gmp-openh264.cpp
+++ b/module/gmp-openh264.cpp
@@ -930,14 +930,25 @@ class OpenH264VideoDecoder : public GMPVideoDecoder, public RefCounted {
break;
case GMP_BufferLength32: {
+ static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 };
uint8_t* start_code = inputFrame->Buffer();
- // start code should be at least four bytes from the end or we risk
- // reading/writing outside the buffer.
- while (start_code < inputFrame->Buffer() + inputFrame->Size() - 4) {
- static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 };
- uint8_t* lenp = start_code;
- start_code += * (reinterpret_cast<int32_t*> (lenp));
- memcpy (lenp, code, 4);
+ uint32_t remaining = inputFrame->Size();
+
+ // Keep old semantics: length field includes the 4-byte length header.
+ while (remaining >= sizeof (uint32_t)) {
+ uint32_t nal_length = 0;
+ memcpy (&nal_length, start_code, sizeof (nal_length));
+ if (nal_length <= sizeof (uint32_t) || nal_length > remaining) {
+ GMPLOG (GL_ERROR, "Malformed GMP_BufferLength32 frame: nal_length="
+ << nal_length << " remaining=" << remaining);
+ inputFrame->Destroy();
+ Error (GMPDecodeErr);
+ return;
+ }
+
+ memcpy (start_code, code, sizeof (code));
+ start_code += nal_length;
+ remaining -= nal_length;
}
}
break;