stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Yaara Rozenblum <yaara.rozenblum@intel.com>,
	Emmanuel Grumbach <emmanuel.grumbach@intel.com>,
	Stanislaw Gruszka <sgruszka@redhat.com>,
	Johannes Berg <johannes.berg@intel.com>
Subject: [PATCH 3.10 14/85] mac80211: fix AP powersave TX vs. wakeup race
Date: Thu, 20 Mar 2014 17:09:17 -0700	[thread overview]
Message-ID: <20140321000600.620200211@linuxfoundation.org> (raw)
In-Reply-To: <20140321000558.606667505@linuxfoundation.org>

3.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

commit 1d147bfa64293b2723c4fec50922168658e613ba upstream.

There is a race between the TX path and the STA wakeup: while
a station is sleeping, mac80211 buffers frames until it wakes
up, then the frames are transmitted. However, the RX and TX
path are concurrent, so the packet indicating wakeup can be
processed while a packet is being transmitted.

This can lead to a situation where the buffered frames list
is emptied on the one side, while a frame is being added on
the other side, as the station is still seen as sleeping in
the TX path.

As a result, the newly added frame will not be send anytime
soon. It might be sent much later (and out of order) when the
station goes to sleep and wakes up the next time.

Additionally, it can lead to the crash below.

Fix all this by synchronising both paths with a new lock.
Both path are not fastpath since they handle PS situations.

In a later patch we'll remove the extra skb queue locks to
reduce locking overhead.

BUG: unable to handle kernel
NULL pointer dereference at 000000b0
IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
*pde = 00000000
Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: ffff0ff0 DR7: 00000400
Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
Stack:
 e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
 ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
 ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
Call Trace:
 [<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
 [<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
 [<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
 [<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
 [<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
 [<c149ef70>] dev_hard_start_xmit+0x450/0x950
 [<c14b9aa9>] sch_direct_xmit+0xa9/0x250
 [<c14b9c9b>] __qdisc_run+0x4b/0x150
 [<c149f732>] dev_queue_xmit+0x2c2/0xca0

Reported-by: Yaara Rozenblum <yaara.rozenblum@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
[reword commit log, use a separate lock]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 net/mac80211/sta_info.c |    4 ++++
 net/mac80211/sta_info.h |    7 +++----
 net/mac80211/tx.c       |   15 +++++++++++++++
 3 files changed, 22 insertions(+), 4 deletions(-)

--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -339,6 +339,7 @@ struct sta_info *sta_info_alloc(struct i
 		return NULL;
 
 	spin_lock_init(&sta->lock);
+	spin_lock_init(&sta->ps_lock);
 	INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
 	INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
 	mutex_init(&sta->ampdu_mlme.mtx);
@@ -1045,6 +1046,8 @@ void ieee80211_sta_ps_deliver_wakeup(str
 
 	skb_queue_head_init(&pending);
 
+	/* sync with ieee80211_tx_h_unicast_ps_buf */
+	spin_lock(&sta->ps_lock);
 	/* Send all buffered frames to the station */
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 		int count = skb_queue_len(&pending), tmp;
@@ -1064,6 +1067,7 @@ void ieee80211_sta_ps_deliver_wakeup(str
 	}
 
 	ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
+	spin_unlock(&sta->ps_lock);
 
 	local->total_ps_buffered -= buffered;
 
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -244,6 +244,7 @@ struct sta_ampdu_mlme {
  * @drv_unblock_wk: used for driver PS unblocking
  * @listen_interval: listen interval of this station, when we're acting as AP
  * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
+ * @ps_lock: used for powersave (when mac80211 is the AP) related locking
  * @ps_tx_buf: buffers (per AC) of frames to transmit to this station
  *	when it leaves power saving state or polls
  * @tx_filtered: buffers (per AC) of frames we already tried to
@@ -324,10 +325,8 @@ struct sta_info {
 	/* use the accessors defined below */
 	unsigned long _flags;
 
-	/*
-	 * STA powersave frame queues, no more than the internal
-	 * locking required.
-	 */
+	/* STA powersave lock and frame queues */
+	spinlock_t ps_lock;
 	struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
 	struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
 	unsigned long driver_buffered_tids;
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -461,6 +461,20 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
 		       sta->sta.addr, sta->sta.aid, ac);
 		if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
 			purge_old_ps_buffers(tx->local);
+
+		/* sync with ieee80211_sta_ps_deliver_wakeup */
+		spin_lock(&sta->ps_lock);
+		/*
+		 * STA woke up the meantime and all the frames on ps_tx_buf have
+		 * been queued to pending queue. No reordering can happen, go
+		 * ahead and Tx the packet.
+		 */
+		if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
+		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
+			spin_unlock(&sta->ps_lock);
+			return TX_CONTINUE;
+		}
+
 		if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
 			struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
 			ps_dbg(tx->sdata,
@@ -474,6 +488,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
 		info->control.vif = &tx->sdata->vif;
 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 		skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
+		spin_unlock(&sta->ps_lock);
 
 		if (!timer_pending(&local->sta_cleanup))
 			mod_timer(&local->sta_cleanup,



  parent reply	other threads:[~2014-03-21  0:09 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-21  0:09 [PATCH 3.10 00/85] 3.10.34-stable review Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 01/85] ocfs2: fix quota file corruption Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 02/85] ocfs2 syncs the wrong range Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 03/85] sched: Fix double normalization of vruntime Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 04/85] rapidio/tsi721: fix tasklet termination in dma channel release Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 05/85] net-tcp: fastopen: fix high order allocations Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 06/85] neigh: recompute reachabletime before returning from neigh_periodic_work() Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 07/85] virtio-net: alloc big buffers also when guest can receive UFO Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 08/85] ipv6: reuse ip6_frag_id from ip6_ufo_append_data Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 09/85] sfc: check for NULL efx->ptp_data in efx_ptp_event Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 10/85] ipv6: ipv6_find_hdr restore prev functionality Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 11/85] tg3: Dont check undefined error bits in RXBD Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 12/85] net: sctp: fix sctp_sf_do_5_1D_ce to verify if we/peer is AUTH capable Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 13/85] mac80211: send control port protocol frames to the VO queue Greg Kroah-Hartman
2014-03-21  0:09 ` Greg Kroah-Hartman [this message]
2014-03-21  0:09 ` [PATCH 3.10 15/85] mac80211: dont validate unchanged AP bandwidth while tracking Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 16/85] mac80211: fix association to 20/40 MHz VHT networks Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 17/85] mac80211: clear sequence/fragment number in QoS-null frames Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 18/85] ath9k: Fix ETSI compliance for AR9462 2.0 Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 19/85] iwlwifi: dvm: clear IWL_STA_UCODE_INPROGRESS when assoc fails Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 20/85] iwlwifi: fix TX status for aggregated packets Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 21/85] iwlwifi: disable TX AMPDU by default for iwldvm Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 22/85] mwifiex: clean pcie ring only when device is present Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 23/85] mwifiex: add NULL check for PCIe Rx skb Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 24/85] mwifiex: fix cmd and Tx data timeout issue for PCIe cards Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 25/85] mwifiex: do not advertise usb autosuspend support Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 26/85] mwifiex: copy APs HT capability info correctly Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 27/85] mwifiex: save and copy APs VHT " Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 28/85] ARM: 7811/1: locks: use early clobber in arch_spin_trylock Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 30/85] ALSA: oxygen: Xonar DG(X): capture from I2S channel 1, not 2 Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 31/85] ALSA: usb-audio: Add quirk for Logitech Webcam C500 Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 32/85] ALSA: hda - Added inverted digital-mic handling for Acer TravelMate 8371 Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 33/85] ALSA: hda - Add missing loopback merge path for AD1884/1984 codecs Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 34/85] powerpc: Align p_dyn, p_rela and p_st symbols Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 35/85] ARM: 7991/1: sa1100: fix compile problem on Collie Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 36/85] regulator: core: Replace direct ops->enable usage Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 37/85] x86: Ignore NMIs that come in during early boot Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 38/85] x86: fix compile error due to X86_TRAP_NMI use in asm files Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 39/85] x86/amd/numa: Fix northbridge quirk to assign correct NUMA node Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 40/85] usb: Add device quirk for Logitech HD Pro Webcams C920 and C930e Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 41/85] usb: Make DELAY_INIT quirk wait 100ms between Get Configuration requests Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 42/85] genirq: Remove racy waitqueue_active check Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 43/85] cpuset: fix a race condition in __cpuset_node_allowed_softwall() Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 44/85] ACPI / resources: ignore invalid ACPI device resources Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 45/85] tracing: Do not add event files for modules that fail tracepoints Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 46/85] firewire: net: fix use after free Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 47/85] firewire: dont use PREPARE_DELAYED_WORK Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 48/85] libata: add ATA_HORKAGE_BROKEN_FPDMA_AA quirk for Seagate Momentus SpinPoint M8 (2BA30001) Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 49/85] spi: spi-ath79: fix initial GPIO CS line setup Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 50/85] NFS: Fix a delegation callback race Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 51/85] NFSv4: nfs4_stateid_is_current should return true for an invalid stateid Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 52/85] ACPI / sleep: Add extra checks for HW Reduced ACPI mode sleep states Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 53/85] iscsi-target: Fix iscsit_get_tpg_from_np tpg_state bug Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 54/85] fs/proc/base.c: fix GPF in /proc/$PID/map_files Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 55/85] drm/radeon/atom: select the proper number of lanes in transmitter setup Greg Kroah-Hartman
2014-03-21  0:09 ` [PATCH 3.10 56/85] ASoC: pcm: free path list before exiting from error conditions Greg Kroah-Hartman
2014-03-22 18:55   ` Mark Brown
2014-03-24  4:34     ` Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 57/85] ipc: Fix 2 bugs in msgrcv() MSG_COPY implementation Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 59/85] PCI: Enable INTx in pci_reenable_device() only when MSI/MSI-X not enabled Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 60/85] vmxnet3: fix netpoll race condition Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 61/85] vmxnet3: fix building without CONFIG_PCI_MSI Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 62/85] mm/compaction: break out of loop on !PageBuddy in isolate_freepages_block Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 63/85] dm cache: fix truncation bug when copying a block to/from >2TB fast device Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 64/85] dm cache: fix access beyond end of origin device Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 65/85] net: unix socket code abuses csum_partial Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 66/85] can: flexcan: flexcan_open(): fix error path if flexcan_chip_start() fails Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 67/85] SCSI: isci: fix reset timeout handling Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 68/85] SCSI: isci: correct erroneous for_each_isci_host macro Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 69/85] SCSI: qla2xxx: Poll during initialization for ISP25xx and ISP83xx Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 70/85] SCSI: storvsc: NULL pointer dereference fix Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 71/85] x86, fpu: Check tsk_used_math() in kernel_fpu_end() for eager FPU Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 72/85] Btrfs: fix data corruption when reading/updating compressed extents Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 73/85] ALSA: oxygen: modify adjust_dg_dac_routing function Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 74/85] jiffies: Avoid undefined behavior from signed overflow Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 75/85] s390/dasd: hold request queue sysfs lock when calling elevator_init() Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 76/85] Fix mountpoint reference leakage in linkat Greg Kroah-Hartman
2014-03-21  0:11   ` Oleg Drokin
2014-03-21  0:38     ` Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 78/85] bio-integrity: Fix bio_integrity_verify segment start bug Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 79/85] tick: Make oneshot broadcast robust vs. CPU offlining Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 80/85] iwlwifi: mvm: dont WARN when statistics are handled late Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 81/85] ARM: 7864/1: Handle 64-bit memory in case of 32-bit phys_addr_t Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 82/85] ARM: ignore memory below PHYS_OFFSET Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 83/85] iscsi/iser-target: Use list_del_init for ->i_conn_node Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 84/85] iscsi/iser-target: Fix isert_conn->state hung shutdown issues Greg Kroah-Hartman
2014-03-21  0:10 ` [PATCH 3.10 85/85] iser-target: Fix post_send_buf_count for RDMA READ/WRITE Greg Kroah-Hartman
2014-03-21  5:28 ` [PATCH 3.10 00/85] 3.10.34-stable review Guenter Roeck
2014-03-22 21:56   ` Shuah Khan
2014-03-24  4:35     ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140321000600.620200211@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=emmanuel.grumbach@intel.com \
    --cc=johannes.berg@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sgruszka@redhat.com \
    --cc=stable@vger.kernel.org \
    --cc=yaara.rozenblum@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).