Forráskód Böngészése

qcacmn: Fix potential buffer overflow

Fragment count will be larger than the upper limit which
would lead to an overread of fragment length. Upper limit
check for fragment count is added in this change.

Change-Id: Icc078b2efee554ac84377b5edd90d0a5c7a61f98
CRs-Fixed: 2158922
Zhang Qian 7 éve
szülő
commit
145aef1dfa
1 módosított fájl, 11 hozzáadás és 10 törlés
  1. 11 10
      hif/src/usb/hif_usb.c

+ 11 - 10
hif/src/usb/hif_usb.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -133,21 +133,22 @@ static QDF_STATUS hif_send_internal(HIF_DEVICE_USB *hif_usb_device,
 	int i;
 	struct hif_usb_send_context *send_context;
 	uint8_t frag_count;
-	int head_data_len, tmp_frag_count = 0;
+	uint32_t head_data_len, tmp_frag_count = 0;
 	unsigned char *data_ptr;
 
 	HIF_DBG("+%s pipe : %d, buf:0x%pK nbytes %u",
 		__func__, pipe_id, buf, nbytes);
 
 	frag_count = qdf_nbuf_get_num_frags(buf);
-	if (frag_count > 1) {
+	if (frag_count == 1) {
 		/*
 		 * | hif_usb_send_context | netbuf->data
 		 */
 		head_data_len = sizeof(struct hif_usb_send_context);
-	} else if ((frag_count - 1) < CVG_NBUF_MAX_EXTRA_FRAGS) {
-		/* means have extra fragment buf in skb */
-		/* header data length should be total sending length substract
+	} else if ((frag_count - 1) <= QDF_NBUF_CB_TX_MAX_EXTRA_FRAGS) {
+		/*
+		 * means have extra fragment buf in skb
+		 * header data length should be total sending length substract
 		 * internal data length of netbuf
 		 * | hif_usb_send_context | fragments except internal buffer |
 		 * netbuf->data
@@ -155,15 +156,15 @@ static QDF_STATUS hif_send_internal(HIF_DEVICE_USB *hif_usb_device,
 		head_data_len = sizeof(struct hif_usb_send_context);
 		while (tmp_frag_count < (frag_count - 1)) {
 			head_data_len =
-			    head_data_len +
-			    qdf_nbuf_get_frag_len(buf, tmp_frag_count);
+				head_data_len + qdf_nbuf_get_frag_len(buf,
+						tmp_frag_count);
 			tmp_frag_count = tmp_frag_count + 1;
 		}
 	} else {
 		/* Extra fragments overflow */
 		HIF_ERROR("%s Extra fragments count overflow : %d\n",
-			__func__, frag_count);
-		status = QDF_STATUS_E_FAILURE;
+			  __func__, frag_count);
+		status = QDF_STATUS_E_RESOURCES;
 		goto err;
 	}