Commit f8d1ccf1 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: fix NULL dereference in radiotap code

When receiving failed PLCP frames is enabled, there
won't be a rate pointer when we add the radiotap
header and thus the kernel will crash. Fix this by
not assuming the rate pointer is always valid. It's
still always valid for frames that have good PLCP
though, and that is checked & enforced.

This was broken by my
commit fc885189
Author: Johannes Berg <johannes.berg@intel.com>
Date:   Fri Jul 30 13:23:12 2010 +0200

    mac80211: don't check rates on PLCP error frames

where I removed the check in this case but didn't
take into account that the rate info would be used.
Reported-by: default avatarXiaokang Qin <xiaokang.qin@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent cc438fcc
...@@ -140,8 +140,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, ...@@ -140,8 +140,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos++; pos++;
/* IEEE80211_RADIOTAP_RATE */ /* IEEE80211_RADIOTAP_RATE */
if (status->flag & RX_FLAG_HT) { if (!rate || status->flag & RX_FLAG_HT) {
/* /*
* Without rate information don't add it. If we have,
* MCS information is a separate field in radiotap, * MCS information is a separate field in radiotap,
* added below. The byte here is needed as padding * added below. The byte here is needed as padding
* for the channel though, so initialise it to 0. * for the channel though, so initialise it to 0.
...@@ -162,12 +163,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, ...@@ -162,12 +163,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
else if (status->flag & RX_FLAG_HT) else if (status->flag & RX_FLAG_HT)
put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ, put_unaligned_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ,
pos); pos);
else if (rate->flags & IEEE80211_RATE_ERP_G) else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
pos); pos);
else else if (rate)
put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
pos); pos);
else
put_unaligned_le16(IEEE80211_CHAN_2GHZ, pos);
pos += 2; pos += 2;
/* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment