Commit [r1762]  Maximize  Restore  History

This patch fixes susceptibility to remote abuse of Channel Switch

Announcement Information Elements by injection of Beacon Frame
packets and improves the reliability of channel switch procedure under
conditions of frequent beacon misses.

Currently, channel switch is performed only after receiving Channel Switch
Announcement with Channel Switch Count <= 1. This ensures proper operation
under normal conditions. However, Beacon misses happen (especially if there
is a reason to leave the current channel). If the last Beacon before channel
switch is lost, then STA will remain on the channel. Such a condition is not
fatal, because STA will eventually recover after some time (by scanning for
the BSS and rejoining). It is not optimal, though. The information that a
channel switch is scheduled could have been already known thanks to prior
announcements. Ignoring them is just losing the opportunity to work fluently
under harsh conditions.

Of course it has a drawback. The last (lost) Beacon before scheduled channel
switch could cancel it. If so, then our STA will change the channel, notice
that there is no one to talk to there and then try recover as usual. However,
if we lose last Beacon it is more probable that the channel switch was not
cancelled and thus assuming that we decrease the probability of missing (or
performing an incorrect) channel switch.

BTW It is desirable to pay more attention to received Channel Switch
Announcements to avoid malicious packet injections that can cause a serious

Unfortunately, the "BTW" remark appeared to be true. Using extremely simple
packet injection, an attacker can send his own Beacon Frames with Channel
Switch Announcement Information Elements. If he sets CS Count <= 1, then the
client station (madwifi in STA (Managed) mode) follows it blindly and changes
its operating channel. This completely interrupts communication for a
significant period of time (up to 10 seconds) and therefore current design
can be considered as a serious flaw allowing the attacker to perform DoS attack

The idea to monitor all incoming CSA IEs gives a possibility to avoid such
attacks or at least to reduce their impact to the minimum. Its implementation
has been applied as r962. Its functionality in brief:

* IEEE80211_CSA_PROTECTION_PERIOD has been introduced. It defines the minimal
Channel Switch Count in the initial packet. This means that the period in
which Channel Switch is announced cannot be too short. This protects the
client from switching to another channel after receiving malicious CSA IE
with Count <= 1.
* Interval measurement between subsequent CSA IEs is checked against the
actual CSA Count drop and the right multiplicity of Beacon Interval. It
allows to react to injected packets. The actual action is to cancel the
switch. It is not the ideal solution because now it is easy to enforce
cancelling the switch. However, not to switch is better than to switch ;D,
because the worst impact possible is disruption of communication for a few
seconds needed to scan the band to find the AP. But this can potentially
happen only when the switch is really going to happen and cannot be
triggered by the attacker.
* CSA parameters (Chan, Mode) are monitored for change.
* Channel to switch to is looked up after receiving first CSA IE.
* When any proper CSA IE is received, a timer is set up to make the switch
proceed even though the terminal CSA IE has not arrived. This addresses the
main task described in the ticket description.

The applied changes work fine and do much (if not the most) of what was possible
to ensure proper functioning while using available IEEE802.11h facilities.

Signed-off-by: Michal Wrobel <>

kelmo 2006-10-23

changed /trunk/net80211/ieee80211.h
changed /trunk/net80211/ieee80211_input.c
changed /trunk/net80211/ieee80211_proto.c
changed /trunk/net80211/ieee80211_scan.h
changed /trunk/net80211/ieee80211_var.h
/trunk/net80211/ieee80211.h Diff Switch to side-by-side view
/trunk/net80211/ieee80211_input.c Diff Switch to side-by-side view
/trunk/net80211/ieee80211_proto.c Diff Switch to side-by-side view
/trunk/net80211/ieee80211_scan.h Diff Switch to side-by-side view
/trunk/net80211/ieee80211_var.h Diff Switch to side-by-side view