mips-openwrt-linux-uclibc-gcc 4.5.2 (Linaro GCC 4.5-2011.02-0), the
default compiler for MIPS since r25708, miscompiles send_assoc_resp in
hostapd's src/ap/ieee802_11.c. Specifically, the association ID (AID)
field in the association response frame is set improperly. This gives
a connected STA the wrong idea of what its AID is, causing it to
consult the wrong bit in the traffic information map (TIM) when
determining whether the AP has any data buffered for it. A STA with an
aggressive power saving policy might not switch out of power saving
mode until it has reason to transmit; this will cause delayed or
dropped frame delivery to the STA.

IEEE 802.11-2007 7.3.1.8 says that the association ID (AID) is
transmitted in a 16-bit field, of which the high-order 2 bits must be
set to 1, and the low-order 14 bits are significant and represent the
actual AID value. The code generation bug causes the low-order 8 bits
of the field to always be set to 1. For example, AID 1 would normally
be transmitted in an association response frame as 0x01 0xc0 (in
little-endian byte order); this bug causes it to be transmitted as
0xff 0xc0. The STA would consult bit 255 instead of bit 1 in the TIM.

Splitting the AID value out into its own temporary variable is enough
to avoid the bad code generation. I only experienced a problem with
the AID field, but chose to make the same change for the capability
information field for good measure.

I can provide annotated examples of code generation if anyone's
interested. In addition to 4.5.2 (Linaro GCC 4.5-2011.02-0), I tested
4.3.3 (CodeSourcery), 4.4.5 (GCC), and mainline 4.5.2 (GCC). None of
the other compilers miscompiled this code. Since this bug is
restricted to Linaro GCC 4.5 targeting MIPS, and I doubt many others
are targeting MIPS with this compiler, I'm not sending this patch
upstream to hostapd at this point.

Signed-off-by: Mark Mentovai <m...@moxienet.com>
---
Index: package/hostapd/patches/001-mips_linaro_gcc45_codegen.patch
===================================================================
--- package/hostapd/patches/001-mips_linaro_gcc45_codegen.patch (revision 0)
+++ package/hostapd/patches/001-mips_linaro_gcc45_codegen.patch (revision 0)
@@ -0,0 +1,18 @@
+--- a/src/ap/ieee802_11.c
++++ b/src/ap/ieee802_11.c
+@@ -837,11 +837,11 @@
+
+       send_len = IEEE80211_HDRLEN;
+       send_len += sizeof(reply->u.assoc_resp);
+-      reply->u.assoc_resp.capab_info =
+-              host_to_le16(hostapd_own_capab_info(hapd, sta, 0));
++      u16 capab_info = hostapd_own_capab_info(hapd, sta, 0);
++      reply->u.assoc_resp.capab_info = host_to_le16(capab_info);
+       reply->u.assoc_resp.status_code = host_to_le16(status_code);
+-      reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0)
+-                                             | BIT(14) | BIT(15));
++      u16 aid = sta ? sta->aid : 0;
++      reply->u.assoc_resp.aid = host_to_le16(aid | BIT(14) | BIT(15));
+       /* Supported rates */
+       p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
+       /* Extended supported rates */
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to