Explorar o código

qcacmn: Fix potential buffer overflow

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

Change-Id: Ib4ba4047f5eea89c09a92f89cf72e1976e0c9f3c
Keyur Parekh %!s(int64=7) %!d(string=hai) anos
pai
achega
45393697a8
Modificáronse 1 ficheiros con 14 adicións e 6 borrados
  1. 14 6
      hif/src/usb/hif_usb.c

+ 14 - 6
hif/src/usb/hif_usb.c

@@ -132,14 +132,21 @@ static QDF_STATUS hif_send_internal(HIF_DEVICE_USB *hif_usb_device,
 	int usb_status;
 	int i;
 	struct hif_usb_send_context *send_context;
-	int frag_count = 0, head_data_len, tmp_frag_count = 0;
+	uint8_t frag_count;
+	int 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) {	/* means have extra fragment buf in skb */
+	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
 		 * internal data length of netbuf
 		 * | hif_usb_send_context | fragments except internal buffer |
@@ -153,10 +160,11 @@ static QDF_STATUS hif_send_internal(HIF_DEVICE_USB *hif_usb_device,
 			tmp_frag_count = tmp_frag_count + 1;
 		}
 	} else {
-		/*
-		 * | hif_usb_send_context | netbuf->data
-		 */
-		head_data_len = sizeof(struct hif_usb_send_context);
+		/* Extra fragments overflow */
+		HIF_ERROR("%s Extra fragments count overflow : %d\n",
+			__func__, frag_count);
+		status = QDF_STATUS_E_FAILURE;
+		goto err;
 	}
 
 	/* Check whether head room is enough to save extra head data */