All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ath11k: fix kernel panic by freeing the msdu received with invalid length
@ 2020-05-04 16:59 ` Tamizh Chelvam
  0 siblings, 0 replies; 6+ messages in thread
From: Tamizh Chelvam @ 2020-05-04 16:59 UTC (permalink / raw)
  To: ath11k; +Cc: linux-wireless, Tamizh Chelvam

In certain scenario host receives the packets with invalid length
which causes below kernel panic. Free up those msdus to avoid
this kernel panic.

 2270.028121:   <6> task: ffffffc0008306d0 ti: ffffffc0008306d0 task.ti: ffffffc0008306d0
 2270.035247:   <2> PC is at skb_panic+0x40/0x44
 2270.042784:   <2> LR is at skb_panic+0x40/0x44
 2270.521775:   <2> [<ffffffc0004a06e0>] skb_panic+0x40/0x44
 2270.524039:   <2> [<ffffffc0004a1278>] skb_put+0x54/0x5c
 2270.529264:   <2> [<ffffffbffcc373a8>] ath11k_dp_process_rx_err+0x320/0x5b0 [ath11k]
 2270.533860:   <2> [<ffffffbffcc30b68>] ath11k_dp_service_srng+0x80/0x268 [ath11k]
 2270.541063:   <2> [<ffffffbffcc1d554>] ath11k_hal_rx_reo_ent_buf_paddr_get+0x200/0xb64 [ath11k]
 2270.547917:   <2> [<ffffffc0004b1f74>] net_rx_action+0xf8/0x274
 2270.556247:   <2> [<ffffffc000099df4>] __do_softirq+0x128/0x228
 2270.561625:   <2> [<ffffffc00009a130>] irq_exit+0x84/0xcc
 2270.567008:   <2> [<ffffffc0000cfb28>] __handle_domain_irq+0x8c/0xb0
 2270.571695:   <2> [<ffffffc000082484>] gic_handle_irq+0x6c/0xbc

Signed-off-by: Tamizh Chelvam <tamizhr@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 47ad3bd..90d2d47 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2270,6 +2270,7 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
 	struct ieee80211_hdr *hdr;
 	struct sk_buff *last_buf;
 	u8 l3_pad_bytes;
+	u8 *hdr_status;
 	u16 msdu_len;
 	int ret;
 
@@ -2298,8 +2299,13 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
 		skb_pull(msdu, HAL_RX_DESC_SIZE);
 	} else if (!rxcb->is_continuation) {
 		if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+			hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
 			ret = -EINVAL;
 			ath11k_warn(ar->ab, "invalid msdu len %u\n", msdu_len);
+			ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+					sizeof(struct ieee80211_hdr));
+			ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
+					sizeof(struct hal_rx_desc));
 			goto free_out;
 		}
 		skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len);
@@ -3394,6 +3400,7 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
 	struct sk_buff *msdu;
 	struct ath11k_skb_rxcb *rxcb;
 	struct hal_rx_desc *rx_desc;
+	u8 *hdr_status;
 	u16 msdu_len;
 
 	spin_lock_bh(&rx_ring->idr_lock);
@@ -3431,6 +3438,17 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
 
 	rx_desc = (struct hal_rx_desc *)msdu->data;
 	msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc);
+	if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+		hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
+		ath11k_warn(ar->ab, "invalid msdu leng %u", msdu_len);
+		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+				sizeof(struct ieee80211_hdr));
+		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
+				sizeof(struct hal_rx_desc));
+		dev_kfree_skb_any(msdu);
+		goto exit;
+	}
+
 	skb_put(msdu, HAL_RX_DESC_SIZE + msdu_len);
 
 	if (ath11k_dp_rx_frag_h_mpdu(ar, msdu, ring_desc)) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH] ath11k: fix kernel panic by freeing the msdu received with invalid length
@ 2020-05-04 16:59 ` Tamizh Chelvam
  0 siblings, 0 replies; 6+ messages in thread
From: Tamizh Chelvam @ 2020-05-04 16:59 UTC (permalink / raw)
  To: ath11k; +Cc: linux-wireless, Tamizh Chelvam

In certain scenario host receives the packets with invalid length
which causes below kernel panic. Free up those msdus to avoid
this kernel panic.

 2270.028121:   <6> task: ffffffc0008306d0 ti: ffffffc0008306d0 task.ti: ffffffc0008306d0
 2270.035247:   <2> PC is at skb_panic+0x40/0x44
 2270.042784:   <2> LR is at skb_panic+0x40/0x44
 2270.521775:   <2> [<ffffffc0004a06e0>] skb_panic+0x40/0x44
 2270.524039:   <2> [<ffffffc0004a1278>] skb_put+0x54/0x5c
 2270.529264:   <2> [<ffffffbffcc373a8>] ath11k_dp_process_rx_err+0x320/0x5b0 [ath11k]
 2270.533860:   <2> [<ffffffbffcc30b68>] ath11k_dp_service_srng+0x80/0x268 [ath11k]
 2270.541063:   <2> [<ffffffbffcc1d554>] ath11k_hal_rx_reo_ent_buf_paddr_get+0x200/0xb64 [ath11k]
 2270.547917:   <2> [<ffffffc0004b1f74>] net_rx_action+0xf8/0x274
 2270.556247:   <2> [<ffffffc000099df4>] __do_softirq+0x128/0x228
 2270.561625:   <2> [<ffffffc00009a130>] irq_exit+0x84/0xcc
 2270.567008:   <2> [<ffffffc0000cfb28>] __handle_domain_irq+0x8c/0xb0
 2270.571695:   <2> [<ffffffc000082484>] gic_handle_irq+0x6c/0xbc

Signed-off-by: Tamizh Chelvam <tamizhr@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 47ad3bd..90d2d47 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2270,6 +2270,7 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
 	struct ieee80211_hdr *hdr;
 	struct sk_buff *last_buf;
 	u8 l3_pad_bytes;
+	u8 *hdr_status;
 	u16 msdu_len;
 	int ret;
 
@@ -2298,8 +2299,13 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
 		skb_pull(msdu, HAL_RX_DESC_SIZE);
 	} else if (!rxcb->is_continuation) {
 		if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+			hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
 			ret = -EINVAL;
 			ath11k_warn(ar->ab, "invalid msdu len %u\n", msdu_len);
+			ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+					sizeof(struct ieee80211_hdr));
+			ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
+					sizeof(struct hal_rx_desc));
 			goto free_out;
 		}
 		skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len);
@@ -3394,6 +3400,7 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
 	struct sk_buff *msdu;
 	struct ath11k_skb_rxcb *rxcb;
 	struct hal_rx_desc *rx_desc;
+	u8 *hdr_status;
 	u16 msdu_len;
 
 	spin_lock_bh(&rx_ring->idr_lock);
@@ -3431,6 +3438,17 @@ static int ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
 
 	rx_desc = (struct hal_rx_desc *)msdu->data;
 	msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc);
+	if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+		hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
+		ath11k_warn(ar->ab, "invalid msdu leng %u", msdu_len);
+		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+				sizeof(struct ieee80211_hdr));
+		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
+				sizeof(struct hal_rx_desc));
+		dev_kfree_skb_any(msdu);
+		goto exit;
+	}
+
 	skb_put(msdu, HAL_RX_DESC_SIZE + msdu_len);
 
 	if (ath11k_dp_rx_frag_h_mpdu(ar, msdu, ring_desc)) {
-- 
1.9.1

_______________________________________________
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] ath11k: fix kernel panic by freeing the msdu received with invalid length
  2020-05-04 16:59 ` Tamizh Chelvam
  (?)
@ 2020-05-06  6:16 ` Kalle Valo
  -1 siblings, 0 replies; 6+ messages in thread
From: Kalle Valo @ 2020-05-06  6:16 UTC (permalink / raw)
  To: Tamizh Chelvam; +Cc: ath11k, linux-wireless, Tamizh Chelvam

Tamizh Chelvam <tamizhr@codeaurora.org> wrote:

> In certain scenario host receives the packets with invalid length
> which causes below kernel panic. Free up those msdus to avoid
> this kernel panic.
> 
>  2270.028121:   <6> task: ffffffc0008306d0 ti: ffffffc0008306d0 task.ti: ffffffc0008306d0
>  2270.035247:   <2> PC is at skb_panic+0x40/0x44
>  2270.042784:   <2> LR is at skb_panic+0x40/0x44
>  2270.521775:   <2> [<ffffffc0004a06e0>] skb_panic+0x40/0x44
>  2270.524039:   <2> [<ffffffc0004a1278>] skb_put+0x54/0x5c
>  2270.529264:   <2> [<ffffffbffcc373a8>] ath11k_dp_process_rx_err+0x320/0x5b0 [ath11k]
>  2270.533860:   <2> [<ffffffbffcc30b68>] ath11k_dp_service_srng+0x80/0x268 [ath11k]
>  2270.541063:   <2> [<ffffffbffcc1d554>] ath11k_hal_rx_reo_ent_buf_paddr_get+0x200/0xb64 [ath11k]
>  2270.547917:   <2> [<ffffffc0004b1f74>] net_rx_action+0xf8/0x274
>  2270.556247:   <2> [<ffffffc000099df4>] __do_softirq+0x128/0x228
>  2270.561625:   <2> [<ffffffc00009a130>] irq_exit+0x84/0xcc
>  2270.567008:   <2> [<ffffffc0000cfb28>] __handle_domain_irq+0x8c/0xb0
>  2270.571695:   <2> [<ffffffc000082484>] gic_handle_irq+0x6c/0xbc
> 
> Signed-off-by: Tamizh Chelvam <tamizhr@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

d7d43782d541 ath11k: fix kernel panic by freeing the msdu received with invalid length

-- 
https://patchwork.kernel.org/patch/11526757/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ath11k: fix kernel panic by freeing the msdu received with invalid length
  2020-05-04 16:59 ` Tamizh Chelvam
  (?)
  (?)
@ 2020-05-06  6:16 ` Kalle Valo
  -1 siblings, 0 replies; 6+ messages in thread
From: Kalle Valo @ 2020-05-06  6:16 UTC (permalink / raw)
  To: Tamizh Chelvam; +Cc: linux-wireless, ath11k

Tamizh Chelvam <tamizhr@codeaurora.org> wrote:

> In certain scenario host receives the packets with invalid length
> which causes below kernel panic. Free up those msdus to avoid
> this kernel panic.
> 
>  2270.028121:   <6> task: ffffffc0008306d0 ti: ffffffc0008306d0 task.ti: ffffffc0008306d0
>  2270.035247:   <2> PC is at skb_panic+0x40/0x44
>  2270.042784:   <2> LR is at skb_panic+0x40/0x44
>  2270.521775:   <2> [<ffffffc0004a06e0>] skb_panic+0x40/0x44
>  2270.524039:   <2> [<ffffffc0004a1278>] skb_put+0x54/0x5c
>  2270.529264:   <2> [<ffffffbffcc373a8>] ath11k_dp_process_rx_err+0x320/0x5b0 [ath11k]
>  2270.533860:   <2> [<ffffffbffcc30b68>] ath11k_dp_service_srng+0x80/0x268 [ath11k]
>  2270.541063:   <2> [<ffffffbffcc1d554>] ath11k_hal_rx_reo_ent_buf_paddr_get+0x200/0xb64 [ath11k]
>  2270.547917:   <2> [<ffffffc0004b1f74>] net_rx_action+0xf8/0x274
>  2270.556247:   <2> [<ffffffc000099df4>] __do_softirq+0x128/0x228
>  2270.561625:   <2> [<ffffffc00009a130>] irq_exit+0x84/0xcc
>  2270.567008:   <2> [<ffffffc0000cfb28>] __handle_domain_irq+0x8c/0xb0
>  2270.571695:   <2> [<ffffffc000082484>] gic_handle_irq+0x6c/0xbc
> 
> Signed-off-by: Tamizh Chelvam <tamizhr@codeaurora.org>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

d7d43782d541 ath11k: fix kernel panic by freeing the msdu received with invalid length

-- 
https://patchwork.kernel.org/patch/11526757/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

_______________________________________________
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] ath11k: fix kernel panic by freeing the msdu received with invalid length
  2019-11-06  7:14 Tamizh chelvam
@ 2019-11-22 10:34 ` Kalle Valo
  0 siblings, 0 replies; 6+ messages in thread
From: Kalle Valo @ 2019-11-22 10:34 UTC (permalink / raw)
  To: Tamizh chelvam; +Cc: ath11k

Tamizh chelvam <tamizhr@codeaurora.org> writes:

> In certain scenario host receives the packets with invalid
> length which causes below kernel panic. Free up those msdus to avoid this
> kernel panic. And printed packet information for debugging purpose.
>
>  2270.028121:   <6> task: ffffffc0008306d0 ti: ffffffc0008306d0 task.ti: ffffffc0008306d0
>  2270.035247:   <2> PC is at skb_panic+0x40/0x44
>  2270.042784:   <2> LR is at skb_panic+0x40/0x44
>  2270.521775:   <2> [<ffffffc0004a06e0>] skb_panic+0x40/0x44
>  2270.524039:   <2> [<ffffffc0004a1278>] skb_put+0x54/0x5c
>  2270.529264:   <2> [<ffffffbffcc373a8>] ath11k_dp_process_rx_err+0x320/0x5b0 [ath11k]
>  2270.533860:   <2> [<ffffffbffcc30b68>] ath11k_dp_service_srng+0x80/0x268 [ath11k]
>  2270.541063:   <2> [<ffffffbffcc1d554>] ath11k_hal_rx_reo_ent_buf_paddr_get+0x200/0xb64 [ath11k]
>  2270.547917:   <2> [<ffffffc0004b1f74>] net_rx_action+0xf8/0x274
>  2270.556247:   <2> [<ffffffc000099df4>] __do_softirq+0x128/0x228
>  2270.561625:   <2> [<ffffffc00009a130>] irq_exit+0x84/0xcc
>  2270.567008:   <2> [<ffffffc0000cfb28>] __handle_domain_irq+0x8c/0xb0
>  2270.571695:   <2> [<ffffffc000082484>] gic_handle_irq+0x6c/0xbc
>
> Signed-off-by: Tamizh chelvam <tamizhr@codeaurora.org>

Is your lastname uncapitalised on purpose? Looks odd.

> --- a/drivers/net/wireless/ath/ath11k/dp_rx.c
> +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
> @@ -1440,6 +1440,35 @@ static struct sk_buff *ath11k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_
>  	return NULL;
>  }
>  
> +static void ath11k_dp_rx_msdu_info(struct ath11k *ar,
> +				   struct hal_rx_desc *rx_desc,
> +				   struct ath11k_skb_rxcb *rxcb)
> +{
> +	enum hal_encrypt_type enctype;
> +	bool is_decrypted;
> +	bool mpdu_len_err;
> +	u32 decap_format;
> +	u8 *hdr_status;
> +	u16 msdu_len;
> +
> +	hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
> +	msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc);
> +	rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(rx_desc);
> +	rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(rx_desc);
> +
> +	decap_format = ath11k_dp_rxdesc_get_decap_format(rx_desc);
> +	mpdu_len_err = !!ath11k_dp_rxdesc_get_mpdulen_err(rx_desc);
> +
> +	is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);
> +	enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc);
> +
> +	ath11k_warn(ar->ab, "frame rx with invalid msdu len %u first msdu %d last msdu %d decap format %u mpdu_len_err %d decrypted %d encryption type %u\n",
> +		    msdu_len, rxcb->is_first_msdu, rxcb->is_last_msdu,
> +		    decap_format, mpdu_len_err, is_decrypted, enctype);
> +	ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
> +			sizeof(struct ieee80211_hdr));
> +}

This function feels quite excessive. The warning messages are supposed
to be concise and printing 7 different values is far from that. So I
would prefer to drop this function altogether.

>  static int ath11k_dp_rx_retrieve_amsdu(struct ath11k *ar,
>  				       struct sk_buff_head *msdu_list,
>  				       struct sk_buff_head *amsdu_list)
> @@ -1492,6 +1521,12 @@ static int ath11k_dp_rx_retrieve_amsdu(struct ath11k *ar,
>  		l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(lrx_desc);
>  
>  		if (!rxcb->is_continuation) {
> +			if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
> +				ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
> +						sizeof(struct hal_rx_desc));
> +				ath11k_dp_rx_msdu_info(ar, rx_desc, rxcb);
> +				goto free_out;
> +			}

So instead I would just print a warning like this:

"dropping received amsdu frame with invalid msdu length %u"

And also call ath11k_dbg_dump() here.

>  			skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len);
>  			skb_pull(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes);
>  		} else {
> @@ -2764,6 +2799,14 @@ static void ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
>  
>  	rx_desc = (struct hal_rx_desc *)msdu->data;
>  	msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc);
> +	if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
> +		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
> +				sizeof(struct hal_rx_desc));
> +		ath11k_dp_rx_msdu_info(ar, rx_desc, rxcb);
> +		dev_kfree_skb_any(msdu);
> +		goto exit;
> +	}

And the same here, but change the message a bit to make it unique to
make it easier to find when reading logs:

"dropping received fragmented frame with invalid msdu length %u"

I just made up terms "amsdu" and "fragmented" from function names,
please do come up with more appropriate terms if they are not correct.

-- 
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

_______________________________________________
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] ath11k: fix kernel panic by freeing the msdu received with invalid length
@ 2019-11-06  7:14 Tamizh chelvam
  2019-11-22 10:34 ` Kalle Valo
  0 siblings, 1 reply; 6+ messages in thread
From: Tamizh chelvam @ 2019-11-06  7:14 UTC (permalink / raw)
  To: ath11k; +Cc: Tamizh chelvam

In certain scenario host receives the packets with invalid
length which causes below kernel panic. Free up those msdus to avoid this
kernel panic. And printed packet information for debugging purpose.

 2270.028121:   <6> task: ffffffc0008306d0 ti: ffffffc0008306d0 task.ti: ffffffc0008306d0
 2270.035247:   <2> PC is at skb_panic+0x40/0x44
 2270.042784:   <2> LR is at skb_panic+0x40/0x44
 2270.521775:   <2> [<ffffffc0004a06e0>] skb_panic+0x40/0x44
 2270.524039:   <2> [<ffffffc0004a1278>] skb_put+0x54/0x5c
 2270.529264:   <2> [<ffffffbffcc373a8>] ath11k_dp_process_rx_err+0x320/0x5b0 [ath11k]
 2270.533860:   <2> [<ffffffbffcc30b68>] ath11k_dp_service_srng+0x80/0x268 [ath11k]
 2270.541063:   <2> [<ffffffbffcc1d554>] ath11k_hal_rx_reo_ent_buf_paddr_get+0x200/0xb64 [ath11k]
 2270.547917:   <2> [<ffffffc0004b1f74>] net_rx_action+0xf8/0x274
 2270.556247:   <2> [<ffffffc000099df4>] __do_softirq+0x128/0x228
 2270.561625:   <2> [<ffffffc00009a130>] irq_exit+0x84/0xcc
 2270.567008:   <2> [<ffffffc0000cfb28>] __handle_domain_irq+0x8c/0xb0
 2270.571695:   <2> [<ffffffc000082484>] gic_handle_irq+0x6c/0xbc

Signed-off-by: Tamizh chelvam <tamizhr@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/dp_rx.c | 43 +++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index acad746..f2731cd 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1440,6 +1440,35 @@ static struct sk_buff *ath11k_dp_rx_get_msdu_last_buf(struct sk_buff_head *msdu_
 	return NULL;
 }
 
+static void ath11k_dp_rx_msdu_info(struct ath11k *ar,
+				   struct hal_rx_desc *rx_desc,
+				   struct ath11k_skb_rxcb *rxcb)
+{
+	enum hal_encrypt_type enctype;
+	bool is_decrypted;
+	bool mpdu_len_err;
+	u32 decap_format;
+	u8 *hdr_status;
+	u16 msdu_len;
+
+	hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc);
+	msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc);
+	rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(rx_desc);
+	rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(rx_desc);
+
+	decap_format = ath11k_dp_rxdesc_get_decap_format(rx_desc);
+	mpdu_len_err = !!ath11k_dp_rxdesc_get_mpdulen_err(rx_desc);
+
+	is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);
+	enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc);
+
+	ath11k_warn(ar->ab, "frame rx with invalid msdu len %u first msdu %d last msdu %d decap format %u mpdu_len_err %d decrypted %d encryption type %u\n",
+		    msdu_len, rxcb->is_first_msdu, rxcb->is_last_msdu,
+		    decap_format, mpdu_len_err, is_decrypted, enctype);
+	ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", hdr_status,
+			sizeof(struct ieee80211_hdr));
+}
+
 static int ath11k_dp_rx_retrieve_amsdu(struct ath11k *ar,
 				       struct sk_buff_head *msdu_list,
 				       struct sk_buff_head *amsdu_list)
@@ -1492,6 +1521,12 @@ static int ath11k_dp_rx_retrieve_amsdu(struct ath11k *ar,
 		l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(lrx_desc);
 
 		if (!rxcb->is_continuation) {
+			if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+				ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
+						sizeof(struct hal_rx_desc));
+				ath11k_dp_rx_msdu_info(ar, rx_desc, rxcb);
+				goto free_out;
+			}
 			skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len);
 			skb_pull(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes);
 		} else {
@@ -2764,6 +2799,14 @@ static void ath11k_dp_rx_frag_h_mpdu(struct ath11k *ar,
 
 	rx_desc = (struct hal_rx_desc *)msdu->data;
 	msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc);
+	if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) {
+		ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc,
+				sizeof(struct hal_rx_desc));
+		ath11k_dp_rx_msdu_info(ar, rx_desc, rxcb);
+		dev_kfree_skb_any(msdu);
+		goto exit;
+	}
+
 	skb_put(msdu, HAL_RX_DESC_SIZE + msdu_len);
 	skb_pull(msdu, HAL_RX_DESC_SIZE);
 
-- 
1.9.1


_______________________________________________
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-05-06  6:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-04 16:59 [PATCH] ath11k: fix kernel panic by freeing the msdu received with invalid length Tamizh Chelvam
2020-05-04 16:59 ` Tamizh Chelvam
2020-05-06  6:16 ` Kalle Valo
2020-05-06  6:16 ` Kalle Valo
  -- strict thread matches above, loose matches on Subject: below --
2019-11-06  7:14 Tamizh chelvam
2019-11-22 10:34 ` Kalle Valo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.