summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsiu-Chang Chen <hsiuchangchen@google.com>2020-12-16 16:41:41 +0530
committerHsiu-Chang Chen <hsiuchangchen@google.com>2022-06-29 12:24:56 +0800
commit01a62ff8f25dcff90dd68c2940785119754ee92a (patch)
treee7dc996e1fc9c67c3751312fe93f7772d9c02a09
parent8a1e50a6317f96d39033b100e31e83ed439485dd (diff)
downloadwlan-01a62ff8f25dcff90dd68c2940785119754ee92a.tar.gz
WifiHal: Invalid length check for fw-diag msg
Due to invalid length in firmware message, the ring buffer overflows. Added check for length and returned error in case of invalid length. Bug: 231524566 Test: Regression Test Change-Id: I0daeed2335f7fb7661f44bb119776979d51b906d CRs-Fixed: 2837711
-rw-r--r--qcwcn/wifi_hal/ring_buffer.cpp20
-rw-r--r--qcwcn/wifi_hal/wifilogger_diag.cpp15
2 files changed, 33 insertions, 2 deletions
diff --git a/qcwcn/wifi_hal/ring_buffer.cpp b/qcwcn/wifi_hal/ring_buffer.cpp
index d78bd62..1a65bb6 100644
--- a/qcwcn/wifi_hal/ring_buffer.cpp
+++ b/qcwcn/wifi_hal/ring_buffer.cpp
@@ -160,7 +160,7 @@ enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite,
// write in current buffer
unsigned int total_push_in_rd_ptr = 0; // Total amount of push in read pointer in this write
- if (record_length > rbc->each_buf_size) {
+ if (record_length > rbc->each_buf_size || length > rbc->each_buf_size) {
return RB_FAILURE;
}
@@ -279,6 +279,17 @@ enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite,
}
}
rb_unlock(&rbc->rb_rw_lock);
+ if(rbc->bufs[rbc->wr_buf_no].data == NULL || (rbc->bufs[rbc->wr_buf_no].data + rbc->cur_wr_buf_idx) == NULL ||
+ buf == NULL || buf + bytes_written == NULL) {
+ ALOGE("The read or Write buffer is null");
+ return RB_FAILURE;
+ }
+ if (((bytes_written + cur_copy_len) > length
+ || (rbc->cur_wr_buf_idx + cur_copy_len) > rbc->each_buf_size)) {
+ ALOGE("LOG_RB rb_write overflow - cur_copy_len=%d wr_buf[max=%zu no=%d idx=%d] buf[max=%zu accessed=%d]",
+ cur_copy_len, rbc->each_buf_size, rbc->wr_buf_no, rbc->cur_wr_buf_idx, length, bytes_written + cur_copy_len);
+ return RB_FAILURE;
+ }
/* don't use lock while doing memcpy, so that we don't block the read
* context for too long. There is no harm while writing the memory if
@@ -476,7 +487,12 @@ u8 *rb_get_read_buf(void *ctx, size_t *length)
cur_read_len = rbc->cur_wr_buf_idx - rbc->cur_rd_buf_idx;
} else {
/* write is rolled over and just behind the read */
- cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+ if (rbc->bufs[rbc->rd_buf_no].last_wr_index >= rbc->cur_rd_buf_idx) {
+ cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx;
+ } else {
+ ALOGE("Alert: cur_read_len=%u invalid, rd_buf[no=%d rd_idx=%d wr_index=%d]",cur_read_len, rbc->rd_buf_no, rbc->cur_rd_buf_idx, rbc->bufs[rbc->rd_buf_no].last_wr_index);
+ return NULL;
+ }
}
} else {
if (rbc->cur_rd_buf_idx == 0) {
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index d67ba06..4bdfae8 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -1037,6 +1037,11 @@ static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length)
payloadlen = diag_msg_hdr->u.msg_hdr.payload_len;
hdr_size = sizeof(fw_diag_msg_hdr_t);
payload = diag_msg_hdr->payload;
+ if ((count + hdr_size + payloadlen) > length) {
+ ALOGE("WLAN_DIAG_TYPE_MSG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+ length, count, hdr_size, payloadlen);
+ return WIFI_ERROR_UNKNOWN;
+ }
process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
payloadlen + hdr_size);
break;
@@ -1047,6 +1052,11 @@ static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length)
payloadlen = diag_msg_hdr_v2->u.msg_hdr.payload_len;
hdr_size = sizeof(fw_diag_msg_hdr_v2_t);
payload = diag_msg_hdr_v2->payload;
+ if ((count + hdr_size + payloadlen) > length) {
+ ALOGE("WLAN_DIAG_TYPE_MSG_V2 - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+ length, count, hdr_size, payloadlen);
+ return WIFI_ERROR_UNKNOWN;
+ }
process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr,
payloadlen + hdr_size);
break;
@@ -1058,6 +1068,11 @@ static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u16 length)
payload = diag_msg_hdr->payload;
payloadlen = diag_msg_hdr->u.payload_len;
hdr_size = sizeof(fw_diag_msg_hdr_t);
+ if ((count + hdr_size + payloadlen) > length) {
+ ALOGE("WLAN_DIAG_TYPE_CONFIG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d",
+ length, count, hdr_size, payloadlen);
+ return WIFI_ERROR_UNKNOWN;
+ }
process_firmware_prints(info, (u8 *)diag_msg_hdr,
payloadlen + hdr_size);
}