]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
staging: rtl8723bs: fix out-of-bounds read in rtw_get_ie() parser
authorNavaneeth K <knavaneeth786@gmail.com>
Thu, 20 Nov 2025 16:23:52 +0000 (16:23 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Dec 2025 17:37:21 +0000 (18:37 +0100)
commit 154828bf9559b9c8421fc2f0d7f7f76b3683aaed upstream.

The Information Element (IE) parser rtw_get_ie() trusted the length
byte of each IE without validating that the IE body (len bytes after
the 2-byte header) fits inside the remaining frame buffer. A malformed
frame can advertise an IE length larger than the available data, causing
the parser to increment its pointer beyond the buffer end. This results
in out-of-bounds reads or, depending on the pattern, an infinite loop.

Fix by validating that (offset + 2 + len) does not exceed the limit
before accepting the IE or advancing to the next element.

This prevents OOB reads and ensures the parser terminates safely on
malformed frames.

Signed-off-by: Navaneeth K <knavaneeth786@gmail.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/rtl8723bs/core/rtw_ieee80211.c

index 0ed420f3d09628a5f73d4188b018d6cd27c8b59d..5abe2fddc3d7ee21d8d91fe20ecdf1ac0eff0134 100644 (file)
@@ -140,22 +140,24 @@ u8 *rtw_get_ie(u8 *pbuf, signed int index, signed int *len, signed int limit)
        signed int tmp, i;
        u8 *p;
 
-       if (limit < 1)
+       if (limit < 2)
                return NULL;
 
        p = pbuf;
        i = 0;
        *len = 0;
-       while (1) {
+       while (i + 2 <= limit) {
+               tmp = *(p + 1);
+               if (i + 2 + tmp > limit)
+                       break;
+
                if (*p == index) {
-                       *len = *(p + 1);
+                       *len = tmp;
                        return p;
                }
-               tmp = *(p + 1);
+
                p += (tmp + 2);
                i += (tmp + 2);
-               if (i >= limit)
-                       break;
        }
        return NULL;
 }