From: Jouni Malinen Date: Tue, 18 Jul 2023 08:33:37 +0000 (+0300) Subject: WPS: Optimize attribute parsing workaround X-Git-Tag: hostap_2_11~1087 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a4c133ea73c70898dc3414c0a61292c7700ece7f;p=thirdparty%2Fhostap.git WPS: Optimize attribute parsing workaround 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 --- diff --git a/src/wps/wps_attr_parse.c b/src/wps/wps_attr_parse.c index fd5163515..d36443008 100644 --- a/src/wps/wps_attr_parse.c +++ b/src/wps/wps_attr_parse.c @@ -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 "