From: George Joseph Date: Tue, 2 Jun 2026 16:38:59 +0000 (-0600) Subject: ooh323c/ooq931.c: Ensure ooQ931Decode doesn't run out-of-bounds. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e59cbad64deb0b371bbe9ac01f0213bf91d42ce;p=thirdparty%2Fasterisk.git ooh323c/ooq931.c: Ensure ooQ931Decode doesn't run out-of-bounds. Several bounds checks have been edded to ooQ931Decode to prevent it from running past the end of the data buffer when parsing information elements. Resolves: #GHSA-746q-794h-cc7f --- diff --git a/addons/ooh323c/src/ooq931.c b/addons/ooh323c/src/ooq931.c index fe8b06ebee..bdcbae2993 100644 --- a/addons/ooh323c/src/ooq931.c +++ b/addons/ooh323c/src/ooq931.c @@ -89,12 +89,21 @@ EXTERN int ooQ931Decode while (offset < length) { Q931InformationElement *ie; int ieOff = offset; - /* Get field discriminator */ + /* + * Get field discriminator and advance offset to what should be + * the first (or only) byte of the IE length. + */ int discriminator = data[offset++]; - /* For discriminator with high bit set there is no data */ - if ((discriminator & 0x80) == 0) { - int len = data[offset++], alen; + /* + * For discriminator with high bit == 0 there must be data. The + * data length could be in the next 8 or 16 bits so there must be + * at least 1 byte after the discriminator. + * + * Make sure offset is still in-bounds. + */ + if ((discriminator & 0x80) == 0 && offset < length) { + int len = data[offset], alen; if (discriminator == Q931UserUserIE) { /* Special case of User-user field, there is some confusion here as @@ -106,14 +115,39 @@ EXTERN int ooQ931Decode However, at present we assume it is always 2 bytes until we find something that breaks it. */ - len <<= 8; - len |= data[offset++]; - /* we also have a protocol discriminator, which we ignore */ - offset++; + /* + * Advance offset to point to the second byte of the length + * and make sure it's still in-bounds. + */ + if (++offset >= length) { + return Q931_E_INVLENGTH; + } + /* + * Swap the bytes. + * Yes, this assumes we're running on a little-endian system but this is + * the original code from Objective Systems. + */ + len <<= 8; + len |= data[offset]; + + /* + * We also have a nested protocol discriminator, which we ignore. + * Advance offset to point to the nested discriminator + * and make sure it's still in-bounds. + */ + if (++offset >= length) { + return Q931_E_INVLENGTH; + } len--; } + /* + * Advance offset to point to the first data byte. + * We check bounds below. + */ + ++offset; + /* watch out for negative lengths! (ED, 11/5/03) */ if (len < 0) { return Q931_E_INVLENGTH;