diff options
author | Felix Fietkau <nbd@nbd.name> | 2019-01-29 05:10:57 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-02-01 05:08:02 -0500 |
commit | 9d0f50b80222dc273e67e4e14410fcfa4130a90c (patch) | |
tree | 7229938590af7ce21fe995890661bd21047c5005 | |
parent | 5e66e35aab335b83d9ffb220d8a3a13986a7a60e (diff) |
mac80211: ensure that mgmt tx skbs have tailroom for encryption
Some drivers use IEEE80211_KEY_FLAG_SW_MGMT_TX to indicate that management
frames need to be software encrypted. Since normal data packets are still
encrypted by the hardware, crypto_tx_tailroom_needed_cnt gets decremented
after key upload to hw. This can lead to passing skbs to ccmp_encrypt_skb,
which don't have the necessary tailroom for software encryption.
Change the code to add tailroom for encrypted management packets, even if
crypto_tx_tailroom_needed_cnt is 0.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/tx.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f170d6c6629a..928f13a208b0 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1938,9 +1938,16 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1938 | int head_need, bool may_encrypt) | 1938 | int head_need, bool may_encrypt) |
1939 | { | 1939 | { |
1940 | struct ieee80211_local *local = sdata->local; | 1940 | struct ieee80211_local *local = sdata->local; |
1941 | struct ieee80211_hdr *hdr; | ||
1942 | bool enc_tailroom; | ||
1941 | int tail_need = 0; | 1943 | int tail_need = 0; |
1942 | 1944 | ||
1943 | if (may_encrypt && sdata->crypto_tx_tailroom_needed_cnt) { | 1945 | hdr = (struct ieee80211_hdr *) skb->data; |
1946 | enc_tailroom = may_encrypt && | ||
1947 | (sdata->crypto_tx_tailroom_needed_cnt || | ||
1948 | ieee80211_is_mgmt(hdr->frame_control)); | ||
1949 | |||
1950 | if (enc_tailroom) { | ||
1944 | tail_need = IEEE80211_ENCRYPT_TAILROOM; | 1951 | tail_need = IEEE80211_ENCRYPT_TAILROOM; |
1945 | tail_need -= skb_tailroom(skb); | 1952 | tail_need -= skb_tailroom(skb); |
1946 | tail_need = max_t(int, tail_need, 0); | 1953 | tail_need = max_t(int, tail_need, 0); |
@@ -1948,8 +1955,7 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1948 | 1955 | ||
1949 | if (skb_cloned(skb) && | 1956 | if (skb_cloned(skb) && |
1950 | (!ieee80211_hw_check(&local->hw, SUPPORTS_CLONED_SKBS) || | 1957 | (!ieee80211_hw_check(&local->hw, SUPPORTS_CLONED_SKBS) || |
1951 | !skb_clone_writable(skb, ETH_HLEN) || | 1958 | !skb_clone_writable(skb, ETH_HLEN) || enc_tailroom)) |
1952 | (may_encrypt && sdata->crypto_tx_tailroom_needed_cnt))) | ||
1953 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | 1959 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); |
1954 | else if (head_need || tail_need) | 1960 | else if (head_need || tail_need) |
1955 | I802_DEBUG_INC(local->tx_expand_skb_head); | 1961 | I802_DEBUG_INC(local->tx_expand_skb_head); |