瀏覽代碼

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 年之前
父節點
當前提交
145aef1dfa
共有 1 個文件被更改,包括 11 次插入10 次删除
  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;
 	}