diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 0b1b208de767..1824566d08fc 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | |||
@@ -169,9 +169,9 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
169 | } | 169 | } |
170 | 170 | ||
171 | /* iwl_mvm_create_skb Adds the rxb to a new skb */ | 171 | /* iwl_mvm_create_skb Adds the rxb to a new skb */ |
172 | static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, | 172 | static int iwl_mvm_create_skb(struct iwl_mvm *mvm, struct sk_buff *skb, |
173 | u16 len, u8 crypt_len, | 173 | struct ieee80211_hdr *hdr, u16 len, u8 crypt_len, |
174 | struct iwl_rx_cmd_buffer *rxb) | 174 | struct iwl_rx_cmd_buffer *rxb) |
175 | { | 175 | { |
176 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 176 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
177 | struct iwl_rx_mpdu_desc *desc = (void *)pkt->data; | 177 | struct iwl_rx_mpdu_desc *desc = (void *)pkt->data; |
@@ -204,6 +204,20 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, | |||
204 | * present before copying packet data. | 204 | * present before copying packet data. |
205 | */ | 205 | */ |
206 | hdrlen += crypt_len; | 206 | hdrlen += crypt_len; |
207 | |||
208 | if (WARN_ONCE(headlen < hdrlen, | ||
209 | "invalid packet lengths (hdrlen=%d, len=%d, crypt_len=%d)\n", | ||
210 | hdrlen, len, crypt_len)) { | ||
211 | /* | ||
212 | * We warn and trace because we want to be able to see | ||
213 | * it in trace-cmd as well. | ||
214 | */ | ||
215 | IWL_DEBUG_RX(mvm, | ||
216 | "invalid packet lengths (hdrlen=%d, len=%d, crypt_len=%d)\n", | ||
217 | hdrlen, len, crypt_len); | ||
218 | return -EINVAL; | ||
219 | } | ||
220 | |||
207 | skb_put_data(skb, hdr, hdrlen); | 221 | skb_put_data(skb, hdr, hdrlen); |
208 | skb_put_data(skb, (u8 *)hdr + hdrlen + pad_len, headlen - hdrlen); | 222 | skb_put_data(skb, (u8 *)hdr + hdrlen + pad_len, headlen - hdrlen); |
209 | 223 | ||
@@ -216,6 +230,8 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, | |||
216 | skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, | 230 | skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, |
217 | fraglen, rxb->truesize); | 231 | fraglen, rxb->truesize); |
218 | } | 232 | } |
233 | |||
234 | return 0; | ||
219 | } | 235 | } |
220 | 236 | ||
221 | static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm, | 237 | static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm, |
@@ -1671,7 +1687,11 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, | |||
1671 | rx_status->boottime_ns = ktime_get_boot_ns(); | 1687 | rx_status->boottime_ns = ktime_get_boot_ns(); |
1672 | } | 1688 | } |
1673 | 1689 | ||
1674 | iwl_mvm_create_skb(skb, hdr, len, crypt_len, rxb); | 1690 | if (iwl_mvm_create_skb(mvm, skb, hdr, len, crypt_len, rxb)) { |
1691 | kfree_skb(skb); | ||
1692 | goto out; | ||
1693 | } | ||
1694 | |||
1675 | if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc)) | 1695 | if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc)) |
1676 | iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, | 1696 | iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, |
1677 | sta, csi); | 1697 | sta, csi); |