Skip to content
  • Johannes Berg's avatar
    mac80211: fix station/driver powersave race · 5ac2e350
    Johannes Berg authored
    
    
    It is currently possible to have a race due to the station PS
    unblock work like this:
     * station goes to sleep with frames buffered in the driver
     * driver blocks wakeup
     * station wakes up again
     * driver flushes/returns frames, and unblocks, which schedules
       the unblock work
     * unblock work starts to run, and checks that the station is
       awake (i.e. that the WLAN_STA_PS_STA flag isn't set)
     * we process a received frame with PM=1, setting the flag again
     * ieee80211_sta_ps_deliver_wakeup() runs, delivering all frames
       to the driver, and then clearing the WLAN_STA_PS_DRIVER and
       WLAN_STA_PS_STA flags
    
    In this scenario, mac80211 will think that the station is awake,
    while it really is asleep, and any TX'ed frames should be filtered
    by the device (it will know that the station is sleeping) but then
    passed to mac80211 again, which will not buffer it either as it
    thinks the station is awake, and eventually the packets will be
    dropped.
    
    Fix this by moving the clearing of the flags to exactly where we
    learn about the situation. This creates a problem of reordering,
    so introduce another flag indicating that delivery is being done,
    this new flag also queues frames and is cleared only while the
    spinlock is held (which the queuing code also holds) so that any
    concurrent delivery/TX is handled correctly.
    
    Reported-by: default avatarAndrei Otcheretianski <andrei.otcheretianski@intel.com>
    Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
    5ac2e350