]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Optimize attribute parsing workaround
authorJouni Malinen <quic_jouni@quicinc.com>
Tue, 18 Jul 2023 08:33:37 +0000 (11:33 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 18 Jul 2023 08:46:57 +0000 (11:46 +0300)
Optimize the search for nonzero octets when checking for the need to
work around WPS M1 padding. The previous implementation was really
inefficient (O(n^2)) and while that was likely sufficiently fast for the
cases where the MMPDU size limit prevents long buffers (e.g., all P2P
Action frames), it might be able to take tens of seconds on low-end CPUs
with maximum length EAP-WSC messages during WPS provisioning. More
visibly, this was causing OSS-Fuzz to time out a test case with
unrealisticly long data (i.e., almost 10 times the maximum EAP-WSC
buffer length).

Credit to OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60039
Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/wps/wps_attr_parse.c

index fd51635158ac5c646bf8772e0d83200972e9c595..d36443008d9aa87ffe349899a372627951939b8b 100644 (file)
@@ -599,10 +599,15 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
        u16 type, len;
 #ifdef WPS_WORKAROUNDS
        u16 prev_type = 0;
+       size_t last_nonzero = 0;
+       const u8 *start;
 #endif /* WPS_WORKAROUNDS */
 
        os_memset(attr, 0, sizeof(*attr));
        pos = wpabuf_head(msg);
+#ifdef WPS_WORKAROUNDS
+       start = pos;
+#endif /* WPS_WORKAROUNDS */
        end = pos + wpabuf_len(msg);
 
        while (pos < end) {
@@ -649,9 +654,15 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
                         * end of M1. Skip those to avoid interop issues.
                         */
                        int i;
+
+                       if (last_nonzero > (size_t) (pos - start))
+                               continue;
+
                        for (i = 0; i < end - pos; i++) {
-                               if (pos[i])
+                               if (pos[i]) {
+                                       last_nonzero = pos - start + i;
                                        break;
+                               }
                        }
                        if (i == end - pos) {
                                wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "