Add get_unaligned to ieee80211_get_radiotap_len
Subsystems (2)
PATCH 1/1 Add get_unaligned to ieee80211_get_radiotap_len
From: warmcat <[email protected]>
ieee80211_get_radiotap_len() tries to dereference radiotap length without taking care that it is completely unaligned and get_unaligned() is required.
--- net/mac80211/ieee80211.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/mac80211/ieee80211.c +1 -1
@@ -350,7 +350,7 @@ static int ieee80211_get_radiotap_len(struct sk_buff *skb)struct ieee80211_radiotap_header *hdr = (struct ieee80211_radiotap_header *) skb->data; -return le16_to_cpu (hdr->it_len); +return le16_to_cpu (get_unaligned (&hdr->it_len)); }#ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP
Signature · 1 line
1.5.2.4
PATCH 1/1 mac80211: filter locally-originated multicast frames
From: John W. Linville <[email protected]>
In STA mode, the AP will echo our traffic. This includes multicast traffic.
Receiving these frames confuses some protocols and applications, notably IPv6 Duplicate Address Detection.
--- net/mac80211/ieee80211.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
net/mac80211/ieee80211.c +3 -2
@@ -2844,9 +2844,10 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)memcpy (dst, hdr->addr1,ETH_ALEN );memcpy (src, hdr->addr3,ETH_ALEN ); -if (sdata->type !=IEEE80211_IF_TYPE_STA ) { +if (sdata->type !=IEEE80211_IF_TYPE_STA || + (is_multicast_ether_addr (dst) && + !compare_ether_addr (src, dev->dev_addr)))return TXRX_DROP ; - }break ;case 0 :/* DA SA BSSID */
Signature · 1 line
1.5.2.4
PATCH 1/1 Improve sanity checks on injected packets
In reply to John W. LinvilleFrom: warmcat <[email protected]>
Michael Wu noticed that the skb length checking is not taken care of enough when a packet is presented on the Monitor interface for injection.
This patch improves the sanity checking and removes fake offsets placed into the skb network and transport header.
--- net/mac80211/ieee80211.c | 48 ++++++++++++++++++++++++++------------------- 1 files changed, 28 insertions(+), 20 deletions(-)
net/mac80211/ieee80211.c +28 -20
@@ -1680,46 +1680,54 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,struct ieee80211_tx_packet_data *pkt_data;struct ieee80211_radiotap_header *prthdr = (struct ieee80211_radiotap_header *)skb->data; -u16 len; +u16 len_rthdr; -/* -* there must be a radiotap header at the -* start in this case -*/ -if (unlikely (prthdr->it_version)) { -/* only version 0 is supported */ -dev_kfree_skb (skb); -return NETDEV_TX_OK ; - } +/* check for not even having the fixed radiotap header part */ +if (unlikely (skb->len <sizeof (struct ieee80211_radiotap_header ))) + goto fail;/* too short to be possibly valid */ + +/* is it a header version we can trust to find length from? */ +if (unlikely (prthdr->it_version)) + goto fail;/* only version 0 is supported */ + +/* then there must be a radiotap header with a length we can use */ + len_rthdr =ieee80211_get_radiotap_len (skb); + +/* does the skb contain enough to deliver on the alleged length? */ +if (unlikely (skb->len < len_rthdr)) + goto fail;/* skb too short for claimed rt header extent */ skb->dev = local->mdev; pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;memset (pkt_data,0 ,sizeof (*pkt_data)); +/* needed because we set skb device to master */ pkt_data->ifindex = dev->ifindex; + pkt_data->mgmt_iface =0 ; pkt_data->do_not_encrypt =1 ; -/* above needed because we set skb device to master */ -/* * fix up the pointers accounting for the radiotap * header still being in there. We are being given * a precooked IEEE80211 header so no need for * normal processing */ - len =le16_to_cpu (get_unaligned (&prthdr->it_len)); -skb_set_mac_header (skb, len); -skb_set_network_header (skb, len +sizeof (struct ieee80211_hdr )); -skb_set_transport_header (skb, len +sizeof (struct ieee80211_hdr )); - +skb_set_mac_header (skb, len_rthdr);/* -* pass the radiotap header up to -* the next stage intact +* these are just fixed to the end of the rt area since we +* don't have any better information and at this point, nobody cares */ -dev_queue_xmit (skb); +skb_set_network_header (skb, len_rthdr); +skb_set_transport_header (skb, len_rthdr); +/* pass the radiotap header up to the next stage intact */ +dev_queue_xmit (skb);return NETDEV_TX_OK ; + +fail: +dev_kfree_skb (skb); +return NETDEV_TX_OK ;/* meaning, we dealt with the skb */ }
Signature · 1 line
1.5.2.4
PATCH 1/1 libertas: fix endianness breakage
In reply to John W. LinvilleFrom: Al Viro <[email protected]>
wep->keytype[] is u8
--- drivers/net/wireless/libertas/cmd.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/cmd.c +2 -4
@@ -185,14 +185,12 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,switch (pkey->len) {case KEY_LEN_WEP_40 : - wep->keytype[i] = -cpu_to_le16 (cmd_type_wep_40_bit); + wep->keytype[i] = cmd_type_wep_40_bit;memmove (&wep->keymaterial[i], pkey->key, pkey->len);break ;case KEY_LEN_WEP_104 : - wep->keytype[i] = -cpu_to_le16 (cmd_type_wep_104_bit); + wep->keytype[i] = cmd_type_wep_104_bit;memmove (&wep->keymaterial[i], pkey->key, pkey->len);break ;
Signature · 1 line
1.5.2.4
PATCH 1/1 libertas: more endianness breakage
In reply to John W. LinvilleFrom: Al Viro <[email protected]>
domain->header.len is le16 and has just been assigned
cpu_to_le16(arithmetical expression). And all fields of adapter->logmsg are __le32; not a single 16-bit among them...
That's incremental to the previous one
--- drivers/net/wireless/libertas/11d.c | 2 +- drivers/net/wireless/libertas/wext.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/wireless/libertas/11d.c +1 -1
@@ -562,7 +562,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, nr_subband * sizeof(struct ieeetypes_subbandset)); cmd->size =cpu_to_le16 (sizeof (pdomaininfo->action) + - domain->header.len + +le16_to_cpu (domain->header.len) +sizeof (struct mrvlietypesheader ) +S_DS_GEN ); }else {
drivers/net/wireless/libertas/wext.c +4 -4
@@ -973,7 +973,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)/* Quality by TX errors */ priv->wstats.discard.retries = priv->stats.tx_errors; - tx_retries =le16_to_cpu (adapter->logmsg.retry); + tx_retries =le32_to_cpu (adapter->logmsg.retry);if (tx_retries >75 ) tx_qual = (90 - tx_retries) *POOR /15 ;
@@ -989,10 +989,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) (PERFECT -VERY_GOOD ) /50 +VERY_GOOD ; quality =min (quality, tx_qual); - priv->wstats.discard.code =le16_to_cpu (adapter->logmsg.wepundecryptable); - priv->wstats.discard.fragment =le16_to_cpu (adapter->logmsg.rxfrag); + priv->wstats.discard.code =le32_to_cpu (adapter->logmsg.wepundecryptable); + priv->wstats.discard.fragment =le32_to_cpu (adapter->logmsg.rxfrag); priv->wstats.discard.retries = tx_retries; - priv->wstats.discard.misc =le16_to_cpu (adapter->logmsg.ackfailure); + priv->wstats.discard.misc =le32_to_cpu (adapter->logmsg.ackfailure);/* Calculate quality */ priv->wstats.qual.qual =max (quality, (u32 )100 );
Signature · 1 line
1.5.2.4