summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Sarmadi <sona.sarmadi@enea.com>2016-06-17 10:34:58 +0200
committerTudor Florea <tudor.florea@enea.com>2016-06-17 19:49:38 +0200
commit638a72daa5ce011023e0d0311ca48bb454ce9c28 (patch)
tree4ca570430d4952efc548650e36c1a0a9d17a557d
parent8bd62a6ded78e4a1116e23fb66bb5103f856bf89 (diff)
downloadmeta-enea-daisy-enea.tar.gz
Kernel: net: mac80211: CVE-2014-2706daisy-enea
crash dues to AP powersave TX vs. wakeup race Reference: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2706 Reference to upstream fix: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ commit/?id=a7ee1a84a81555b19ec3d02f104bfd70cf0b668a Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> Signed-off-by: Tudor Florea <tudor.florea@enea.com>
-rw-r--r--recipes-kernel/linux/files/mac80211-CVE-2014-2706.patch166
-rw-r--r--recipes-kernel/linux/linux-qoriq-sdk.bbappend1
2 files changed, 167 insertions, 0 deletions
diff --git a/recipes-kernel/linux/files/mac80211-CVE-2014-2706.patch b/recipes-kernel/linux/files/mac80211-CVE-2014-2706.patch
new file mode 100644
index 0000000..5c79ed2
--- /dev/null
+++ b/recipes-kernel/linux/files/mac80211-CVE-2014-2706.patch
@@ -0,0 +1,166 @@
1From a7ee1a84a81555b19ec3d02f104bfd70cf0b668a Mon Sep 17 00:00:00 2001
2From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
3Date: Thu, 20 Feb 2014 09:22:11 +0200
4Subject: mac80211: fix AP powersave TX vs. wakeup race
5
6commit 1d147bfa64293b2723c4fec50922168658e613ba upstream.
7
8There is a race between the TX path and the STA wakeup: while
9a station is sleeping, mac80211 buffers frames until it wakes
10up, then the frames are transmitted. However, the RX and TX
11path are concurrent, so the packet indicating wakeup can be
12processed while a packet is being transmitted.
13
14This can lead to a situation where the buffered frames list
15is emptied on the one side, while a frame is being added on
16the other side, as the station is still seen as sleeping in
17the TX path.
18
19As a result, the newly added frame will not be send anytime
20soon. It might be sent much later (and out of order) when the
21station goes to sleep and wakes up the next time.
22
23Additionally, it can lead to the crash below.
24
25Fix all this by synchronising both paths with a new lock.
26Both path are not fastpath since they handle PS situations.
27
28In a later patch we'll remove the extra skb queue locks to
29reduce locking overhead.
30
31BUG: unable to handle kernel
32NULL pointer dereference at 000000b0
33IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
34*pde = 00000000
35Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
36EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
37EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
38EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
39ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
40 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
41CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
42DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
43DR6: ffff0ff0 DR7: 00000400
44Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
45iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
46Stack:
47 e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
48 ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
49 ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
50Call Trace:
51 [<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
52 [<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
53 [<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
54 [<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
55 [<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
56 [<c149ef70>] dev_hard_start_xmit+0x450/0x950
57 [<c14b9aa9>] sch_direct_xmit+0xa9/0x250
58 [<c14b9c9b>] __qdisc_run+0x4b/0x150
59 [<c149f732>] dev_queue_xmit+0x2c2/0xca0
60
61CVE: CVE-2014-2706
62Upstream-Status: Backport
63
64Reported-by: Yaara Rozenblum <yaara.rozenblum@intel.com>
65Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
66Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
67[reword commit log, use a separate lock]
68Signed-off-by: Johannes Berg <johannes.berg@intel.com>
69Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
70Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
71---
72 net/mac80211/sta_info.c | 4 ++++
73 net/mac80211/sta_info.h | 7 +++----
74 net/mac80211/tx.c | 15 +++++++++++++++
75 3 files changed, 22 insertions(+), 4 deletions(-)
76
77diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
78index 11216bc..a66d006 100644
79--- a/net/mac80211/sta_info.c
80+++ b/net/mac80211/sta_info.c
81@@ -339,6 +339,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
82 return NULL;
83
84 spin_lock_init(&sta->lock);
85+ spin_lock_init(&sta->ps_lock);
86 INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
87 INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
88 mutex_init(&sta->ampdu_mlme.mtx);
89@@ -1045,6 +1046,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
90
91 skb_queue_head_init(&pending);
92
93+ /* sync with ieee80211_tx_h_unicast_ps_buf */
94+ spin_lock(&sta->ps_lock);
95 /* Send all buffered frames to the station */
96 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
97 int count = skb_queue_len(&pending), tmp;
98@@ -1064,6 +1067,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
99 }
100
101 ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
102+ spin_unlock(&sta->ps_lock);
103
104 local->total_ps_buffered -= buffered;
105
106diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
107index adc3004..3184b2b 100644
108--- a/net/mac80211/sta_info.h
109+++ b/net/mac80211/sta_info.h
110@@ -244,6 +244,7 @@ struct sta_ampdu_mlme {
111 * @drv_unblock_wk: used for driver PS unblocking
112 * @listen_interval: listen interval of this station, when we're acting as AP
113 * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
114+ * @ps_lock: used for powersave (when mac80211 is the AP) related locking
115 * @ps_tx_buf: buffers (per AC) of frames to transmit to this station
116 * when it leaves power saving state or polls
117 * @tx_filtered: buffers (per AC) of frames we already tried to
118@@ -324,10 +325,8 @@ struct sta_info {
119 /* use the accessors defined below */
120 unsigned long _flags;
121
122- /*
123- * STA powersave frame queues, no more than the internal
124- * locking required.
125- */
126+ /* STA powersave lock and frame queues */
127+ spinlock_t ps_lock;
128 struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
129 struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
130 unsigned long driver_buffered_tids;
131diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
132index fe9d6e7..6d5791d 100644
133--- a/net/mac80211/tx.c
134+++ b/net/mac80211/tx.c
135@@ -461,6 +461,20 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
136 sta->sta.addr, sta->sta.aid, ac);
137 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
138 purge_old_ps_buffers(tx->local);
139+
140+ /* sync with ieee80211_sta_ps_deliver_wakeup */
141+ spin_lock(&sta->ps_lock);
142+ /*
143+ * STA woke up the meantime and all the frames on ps_tx_buf have
144+ * been queued to pending queue. No reordering can happen, go
145+ * ahead and Tx the packet.
146+ */
147+ if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
148+ !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
149+ spin_unlock(&sta->ps_lock);
150+ return TX_CONTINUE;
151+ }
152+
153 if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
154 struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
155 ps_dbg(tx->sdata,
156@@ -474,6 +488,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
157 info->control.vif = &tx->sdata->vif;
158 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
159 skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
160+ spin_unlock(&sta->ps_lock);
161
162 if (!timer_pending(&local->sta_cleanup))
163 mod_timer(&local->sta_cleanup,
164--
165cgit v0.12
166
diff --git a/recipes-kernel/linux/linux-qoriq-sdk.bbappend b/recipes-kernel/linux/linux-qoriq-sdk.bbappend
index c3ded18..6f76654 100644
--- a/recipes-kernel/linux/linux-qoriq-sdk.bbappend
+++ b/recipes-kernel/linux/linux-qoriq-sdk.bbappend
@@ -22,6 +22,7 @@ SRC_URI += "file://add-no-error-uninitialized.patch \
22 file://virt-kvm-CVE-2013-4587.patch \ 22 file://virt-kvm-CVE-2013-4587.patch \
23 file://floppy-CVE-2014-1737.patch \ 23 file://floppy-CVE-2014-1737.patch \
24 file://floppy-CVE-2014-1738.patch \ 24 file://floppy-CVE-2014-1738.patch \
25 file://mac80211-CVE-2014-2706.patch \
25 file://Fix-CVE-2014-3153.patch \ 26 file://Fix-CVE-2014-3153.patch \
26 file://CVE-2014-0196_n_tty_write_crash.patch \ 27 file://CVE-2014-0196_n_tty_write_crash.patch \
27 file://Fix-CVE-2014-5471_CVE-2014-5472.patch \ 28 file://Fix-CVE-2014-5471_CVE-2014-5472.patch \