qcacld-3.0: Possible Out Of Bound reads in htt_t2h_tx_ppdu_log_print()
mpdu_bytes_array_len, mpdu_msdus_array_len, and msdu_bytes_array_len are used to calculate the record size, as well as used as buffer offset, without any verification. This can cause to multiple overflows and underflow leading to OOB reads. Add checks for each arithmetic operation with these variables. Change-Id: Ib6ec6ac6932eb8c541bc2357d45d3feaf39fdb7d CRs-Fixed: 2226125
This commit is contained in:
parent
14c64fc404
commit
46e0a1354b
@ -832,14 +832,37 @@ htt_t2h_tx_ppdu_log_print(struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr,
|
||||
{
|
||||
int i;
|
||||
int record_size;
|
||||
int calculated_record_size;
|
||||
int num_records;
|
||||
|
||||
record_size =
|
||||
sizeof(*record) +
|
||||
hdr->mpdu_bytes_array_len * sizeof(uint16_t) +
|
||||
hdr->mpdu_msdus_array_len * sizeof(uint8_t) +
|
||||
hdr->msdu_bytes_array_len * sizeof(uint16_t);
|
||||
record_size = sizeof(*record);
|
||||
calculated_record_size = record_size +
|
||||
hdr->mpdu_bytes_array_len * sizeof(uint16_t);
|
||||
if (calculated_record_size < record_size) {
|
||||
qdf_err("Overflow due to record and hdr->mpdu_bytes_array_len %u",
|
||||
hdr->mpdu_bytes_array_len);
|
||||
return;
|
||||
}
|
||||
record_size = calculated_record_size;
|
||||
calculated_record_size += hdr->mpdu_msdus_array_len * sizeof(uint8_t);
|
||||
if (calculated_record_size < record_size) {
|
||||
qdf_err("Overflow due to hdr->mpdu_msdus_array_len %u",
|
||||
hdr->mpdu_msdus_array_len);
|
||||
return;
|
||||
}
|
||||
record_size = calculated_record_size;
|
||||
calculated_record_size += hdr->msdu_bytes_array_len * sizeof(uint16_t);
|
||||
if (calculated_record_size < record_size) {
|
||||
qdf_err("Overflow due to hdr->msdu_bytes_array_len %u",
|
||||
hdr->msdu_bytes_array_len);
|
||||
return;
|
||||
}
|
||||
record_size = calculated_record_size;
|
||||
num_records = (length - sizeof(*hdr)) / record_size;
|
||||
if (num_records < 0) {
|
||||
qdf_err("Underflow due to length %d", length);
|
||||
return;
|
||||
}
|
||||
qdf_debug("Tx PPDU log elements: num_records %d", num_records);
|
||||
|
||||
for (i = 0; i < num_records; i++) {
|
||||
@ -871,6 +894,7 @@ htt_t2h_tx_ppdu_log_print(struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr,
|
||||
#define BUF_SIZE 80
|
||||
char buf[BUF_SIZE];
|
||||
uint8_t *p8;
|
||||
uint8_t *calculated_p8;
|
||||
|
||||
time_enqueue_us =
|
||||
HTT_TICK_TO_USEC(record->timestamp_enqueue,
|
||||
@ -942,7 +966,12 @@ htt_t2h_tx_ppdu_log_print(struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr,
|
||||
}
|
||||
/* skip the regular msg fields to reach the tail area */
|
||||
p8 = (uint8_t *) record;
|
||||
p8 += sizeof(struct ol_fw_tx_dbg_ppdu_base);
|
||||
calculated_p8 = p8 + sizeof(struct ol_fw_tx_dbg_ppdu_base);
|
||||
if (calculated_p8 < p8) {
|
||||
qdf_err("Overflow due to record %p", p8);
|
||||
continue;
|
||||
}
|
||||
p8 = calculated_p8;
|
||||
if (hdr->mpdu_bytes_array_len) {
|
||||
htt_make_u16_list_str((uint32_t *) p8, buf,
|
||||
BUF_SIZE,
|
||||
@ -950,14 +979,26 @@ htt_t2h_tx_ppdu_log_print(struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr,
|
||||
mpdu_bytes_array_len);
|
||||
qdf_debug(" MPDU bytes: %s", buf);
|
||||
}
|
||||
p8 += hdr->mpdu_bytes_array_len * sizeof(uint16_t);
|
||||
calculated_p8 += hdr->mpdu_bytes_array_len * sizeof(uint16_t);
|
||||
if (calculated_p8 < p8) {
|
||||
qdf_err("Overflow due to hdr->mpdu_bytes_array_len %u",
|
||||
hdr->mpdu_bytes_array_len);
|
||||
continue;
|
||||
}
|
||||
p8 = calculated_p8;
|
||||
if (hdr->mpdu_msdus_array_len) {
|
||||
htt_make_u8_list_str((uint32_t *) p8, buf,
|
||||
BUF_SIZE,
|
||||
hdr->mpdu_msdus_array_len);
|
||||
qdf_debug(" MPDU MSDUs: %s", buf);
|
||||
}
|
||||
p8 += hdr->mpdu_msdus_array_len * sizeof(uint8_t);
|
||||
calculated_p8 += hdr->mpdu_msdus_array_len * sizeof(uint8_t);
|
||||
if (calculated_p8 < p8) {
|
||||
qdf_err("Overflow due to hdr->mpdu_msdus_array_len %u",
|
||||
hdr->mpdu_msdus_array_len);
|
||||
continue;
|
||||
}
|
||||
p8 = calculated_p8;
|
||||
if (hdr->msdu_bytes_array_len) {
|
||||
htt_make_u16_list_str((uint32_t *) p8, buf,
|
||||
BUF_SIZE,
|
||||
|
Loading…
Reference in New Issue
Block a user