Explorar o código

qcacmn: fix use after unmap case for HTT packets

When the number of HTT packets in the endpoint TxQueue is more
than MaxTxQueueDepth, we hit the overflow condition. If the
overflow condition is hit, in htc_try_send(), when EpSendFull()
returns HTC_SEND_FULL_KEEP, we try to send all the excess packets.

As part of this logic, we are calling restore_tx_packet(); the
intention of calling resotre_tx_packet() is to just perform
skb_pull_head(), but restore_tx_packet() will also unmap the
HTT packet. Later, when we try to send the excess packets, these
would be already unmapped and when the HW/FW try to access this
unmapped location, it would lead to SMMU fault.

Change-Id: Ie60a302d6a2736f7aa12944b7016d2bdb9ffb10d
CRs-Fixed: 2836444
Manikanta Pubbisetty %!s(int64=4) %!d(string=hai) anos
pai
achega
ade01cf0de
Modificáronse 1 ficheiros con 10 adicións e 1 borrados
  1. 10 1
      htc/htc_send.c

+ 10 - 1
htc/htc_send.c

@@ -121,6 +121,8 @@ static inline void restore_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket)
 	if (pPacket->PktInfo.AsTx.Flags &
 		HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA) {
 		qdf_nbuf_pull_head(netbuf, sizeof(HTC_FRAME_HDR));
+		pPacket->PktInfo.AsTx.Flags &=
+			~HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA;
 	}
 }
 
@@ -1419,7 +1421,12 @@ static enum HTC_SEND_QUEUE_RESULT htc_try_send(HTC_TARGET *target,
 				 * before giving the packet back to the user via
 				 * the EpSendFull callback.
 				 */
-				restore_tx_packet(target, pPacket);
+				qdf_nbuf_pull_head
+					(GET_HTC_PACKET_NET_BUF_CONTEXT
+						(pPacket),
+					sizeof(HTC_FRAME_HDR));
+				pPacket->PktInfo.AsTx.Flags &=
+					~HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA;
 
 				if (pEndpoint->EpCallBacks.
 				    EpSendFull(pEndpoint->EpCallBacks.pContext,
@@ -1444,6 +1451,8 @@ static enum HTC_SEND_QUEUE_RESULT htc_try_send(HTC_TARGET *target,
 						(GET_HTC_PACKET_NET_BUF_CONTEXT
 							(pPacket),
 						sizeof(HTC_FRAME_HDR));
+					pPacket->PktInfo.AsTx.Flags |=
+						HTC_TX_PACKET_FLAG_HTC_HEADER_IN_NETBUF_DATA;
 
 					HTC_PACKET_ENQUEUE(&sendQueue, pPacket);
 				}