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
This commit is contained in:
Keyur Parekh
2017-12-08 16:15:12 -08:00
committed by snandini
parent 8b8f00f622
commit 45393697a8

View File

@@ -132,14 +132,21 @@ static QDF_STATUS hif_send_internal(HIF_DEVICE_USB *hif_usb_device,
int usb_status; int usb_status;
int i; int i;
struct hif_usb_send_context *send_context; 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; unsigned char *data_ptr;
HIF_DBG("+%s pipe : %d, buf:0x%pK nbytes %u", HIF_DBG("+%s pipe : %d, buf:0x%pK nbytes %u",
__func__, pipe_id, buf, nbytes); __func__, pipe_id, buf, nbytes);
frag_count = qdf_nbuf_get_num_frags(buf); 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 /* header data length should be total sending length substract
* internal data length of netbuf * internal data length of netbuf
* | hif_usb_send_context | fragments except internal buffer | * | 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; tmp_frag_count = tmp_frag_count + 1;
} }
} else { } else {
/* /* Extra fragments overflow */
* | hif_usb_send_context | netbuf->data HIF_ERROR("%s Extra fragments count overflow : %d\n",
*/ __func__, frag_count);
head_data_len = sizeof(struct hif_usb_send_context); status = QDF_STATUS_E_FAILURE;
goto err;
} }
/* Check whether head room is enough to save extra head data */ /* Check whether head room is enough to save extra head data */