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>
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) {
* 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 "