From 00ebdfbc89ed160ae45a2fc0f67f36e36dae48ee Mon Sep 17 00:00:00 2001 From: George Joseph Date: Tue, 2 Jun 2026 10:38:59 -0600 Subject: [PATCH] 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 --- addons/ooh323c/src/ooq931.c | 50 +++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) 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;