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 <quic_jouni@quicinc.com>
This commit is contained in:
parent
518ae8c7cc
commit
a4c133ea73
1 changed files with 12 additions and 1 deletions
|
@ -599,10 +599,15 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
|
||||||
u16 type, len;
|
u16 type, len;
|
||||||
#ifdef WPS_WORKAROUNDS
|
#ifdef WPS_WORKAROUNDS
|
||||||
u16 prev_type = 0;
|
u16 prev_type = 0;
|
||||||
|
size_t last_nonzero = 0;
|
||||||
|
const u8 *start;
|
||||||
#endif /* WPS_WORKAROUNDS */
|
#endif /* WPS_WORKAROUNDS */
|
||||||
|
|
||||||
os_memset(attr, 0, sizeof(*attr));
|
os_memset(attr, 0, sizeof(*attr));
|
||||||
pos = wpabuf_head(msg);
|
pos = wpabuf_head(msg);
|
||||||
|
#ifdef WPS_WORKAROUNDS
|
||||||
|
start = pos;
|
||||||
|
#endif /* WPS_WORKAROUNDS */
|
||||||
end = pos + wpabuf_len(msg);
|
end = pos + wpabuf_len(msg);
|
||||||
|
|
||||||
while (pos < end) {
|
while (pos < end) {
|
||||||
|
@ -649,10 +654,16 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
|
||||||
* end of M1. Skip those to avoid interop issues.
|
* end of M1. Skip those to avoid interop issues.
|
||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (last_nonzero > (size_t) (pos - start))
|
||||||
|
continue;
|
||||||
|
|
||||||
for (i = 0; i < end - pos; i++) {
|
for (i = 0; i < end - pos; i++) {
|
||||||
if (pos[i])
|
if (pos[i]) {
|
||||||
|
last_nonzero = pos - start + i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (i == end - pos) {
|
if (i == end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
|
wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
|
||||||
"unexpected message padding");
|
"unexpected message padding");
|
||||||
|
|
Loading…
Reference in a new issue