summaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-03-13 19:42:34 -0400
committerDave Airlie <airlied@redhat.com>2016-03-13 19:46:02 -0400
commit9b61c0fcdf0cfd20a85d9856d46142e7f297de0a (patch)
treed4abe6aa3f4e1e088f9da1d0597e078b1fe58912 /net/mac80211/rx.c
parent550e3b23a53c88adfa46e64f9d442743e65d47da (diff)
parent125234dc8b1cc862f52d8bd5b37c36cc59b2cb86 (diff)
Merge drm-fixes into drm-next.
Nouveau wanted this to avoid some worse conflicts when I merge that.
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bc081850ac0e..60d093f40f1d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1753,7 +1753,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
1753 entry->seq = seq; 1753 entry->seq = seq;
1754 entry->rx_queue = rx_queue; 1754 entry->rx_queue = rx_queue;
1755 entry->last_frag = frag; 1755 entry->last_frag = frag;
1756 entry->ccmp = 0; 1756 entry->check_sequential_pn = false;
1757 entry->extra_len = 0; 1757 entry->extra_len = 0;
1758 1758
1759 return entry; 1759 return entry;
@@ -1849,15 +1849,27 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1849 rx->seqno_idx, &(rx->skb)); 1849 rx->seqno_idx, &(rx->skb));
1850 if (rx->key && 1850 if (rx->key &&
1851 (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || 1851 (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP ||
1852 rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256) && 1852 rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 ||
1853 rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP ||
1854 rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) &&
1853 ieee80211_has_protected(fc)) { 1855 ieee80211_has_protected(fc)) {
1854 int queue = rx->security_idx; 1856 int queue = rx->security_idx;
1855 /* Store CCMP PN so that we can verify that the next 1857
1856 * fragment has a sequential PN value. */ 1858 /* Store CCMP/GCMP PN so that we can verify that the
1857 entry->ccmp = 1; 1859 * next fragment has a sequential PN value.
1860 */
1861 entry->check_sequential_pn = true;
1858 memcpy(entry->last_pn, 1862 memcpy(entry->last_pn,
1859 rx->key->u.ccmp.rx_pn[queue], 1863 rx->key->u.ccmp.rx_pn[queue],
1860 IEEE80211_CCMP_PN_LEN); 1864 IEEE80211_CCMP_PN_LEN);
1865 BUILD_BUG_ON(offsetof(struct ieee80211_key,
1866 u.ccmp.rx_pn) !=
1867 offsetof(struct ieee80211_key,
1868 u.gcmp.rx_pn));
1869 BUILD_BUG_ON(sizeof(rx->key->u.ccmp.rx_pn[queue]) !=
1870 sizeof(rx->key->u.gcmp.rx_pn[queue]));
1871 BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN !=
1872 IEEE80211_GCMP_PN_LEN);
1861 } 1873 }
1862 return RX_QUEUED; 1874 return RX_QUEUED;
1863 } 1875 }
@@ -1872,15 +1884,21 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1872 return RX_DROP_MONITOR; 1884 return RX_DROP_MONITOR;
1873 } 1885 }
1874 1886
1875 /* Verify that MPDUs within one MSDU have sequential PN values. 1887 /* "The receiver shall discard MSDUs and MMPDUs whose constituent
1876 * (IEEE 802.11i, 8.3.3.4.5) */ 1888 * MPDU PN values are not incrementing in steps of 1."
1877 if (entry->ccmp) { 1889 * see IEEE P802.11-REVmc/D5.0, 12.5.3.4.4, item d (for CCMP)
1890 * and IEEE P802.11-REVmc/D5.0, 12.5.5.4.4, item d (for GCMP)
1891 */
1892 if (entry->check_sequential_pn) {
1878 int i; 1893 int i;
1879 u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; 1894 u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
1880 int queue; 1895 int queue;
1896
1881 if (!rx->key || 1897 if (!rx->key ||
1882 (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && 1898 (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP &&
1883 rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256)) 1899 rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 &&
1900 rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP &&
1901 rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256))
1884 return RX_DROP_UNUSABLE; 1902 return RX_DROP_UNUSABLE;
1885 memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); 1903 memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
1886 for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { 1904 for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
@@ -3366,6 +3384,7 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
3366 return false; 3384 return false;
3367 /* ignore action frames to TDLS-peers */ 3385 /* ignore action frames to TDLS-peers */
3368 if (ieee80211_is_action(hdr->frame_control) && 3386 if (ieee80211_is_action(hdr->frame_control) &&
3387 !is_broadcast_ether_addr(bssid) &&
3369 !ether_addr_equal(bssid, hdr->addr1)) 3388 !ether_addr_equal(bssid, hdr->addr1))
3370 return false; 3389 return false;
3371 } 3390 }