msm: vidc: avoid OOB write while accessing memory
Exclude 4 bytes which holds the size of the buffer while calculating
the actual buffer size to avoid OOB write.
Change-Id: I965e78097a3680065aaf7609d35af1a42fc44824
Signed-off-by: Dikshita Agarwal <dikshita@codeaurora.org>
Signed-off-by: Sanjay Singh <sisanj@codeaurora.org>
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 4b51846..5c0419d 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2893,23 +2893,22 @@
return rc;
}
-static void __process_sys_error(struct venus_hfi_device *device)
+static void print_sfr_message(struct venus_hfi_device *device)
{
struct hfi_sfr_struct *vsfr = NULL;
+ u32 vsfr_size = 0;
+ void *p = NULL;
if (__halt_axi(device))
dprintk(VIDC_WARN, "Failed to halt AXI after SYS_ERROR\n");
vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr;
if (vsfr) {
- void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize);
- /*
- * SFR isn't guaranteed to be NULL terminated
- * since SYS_ERROR indicates that Venus is in the
- * process of crashing.
- */
+ vsfr_size = vsfr->bufSize - sizeof(u32);
+ p = memchr(vsfr->rg_data, '\0', vsfr_size);
+ /* SFR isn't guaranteed to be NULL terminated */
if (p == NULL)
- vsfr->rg_data[vsfr->bufSize - 1] = '\0';
+ vsfr->rg_data[vsfr_size - 1] = '\0';
dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
vsfr->rg_data);
@@ -3051,8 +3050,6 @@
}
if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) {
- struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *)
- device->sfr.align_virtual_addr;
struct msm_vidc_cb_info info = {
.response_type = HAL_SYS_WATCHDOG_TIMEOUT,
.response.cmd = {
@@ -3060,9 +3057,7 @@
}
};
- if (vsfr)
- dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
- vsfr->rg_data);
+ print_sfr_message(device);
dprintk(VIDC_ERR, "Received watchdog timeout\n");
packets[packet_count++] = info;
@@ -3088,7 +3083,7 @@
/* Process the packet types that we're interested in */
switch (info->response_type) {
case HAL_SYS_ERROR:
- __process_sys_error(device);
+ print_sfr_message(device);
break;
case HAL_SYS_RELEASE_RESOURCE_DONE:
dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");
diff --git a/drivers/media/platform/msm/vidc_3x/venus_hfi.c b/drivers/media/platform/msm/vidc_3x/venus_hfi.c
index 550e060..2cb7e31 100644
--- a/drivers/media/platform/msm/vidc_3x/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc_3x/venus_hfi.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2012-2016, 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 2018-2020, The Linux Foundation.
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -3306,9 +3307,11 @@
dprintk(VIDC_ERR, "VIDC_CPU_CS_SCIACMDARG0: 0x%x\n", reg);
}
-static void __process_sys_error(struct venus_hfi_device *device)
+static void print_sfr_message(struct venus_hfi_device *device)
{
struct hfi_sfr_struct *vsfr = NULL;
+ u32 vsfr_size = 0;
+ void *p = NULL;
/* Once SYS_ERROR received from HW, it is safe to halt the AXI.
* With SYS_ERROR, Venus FW may have crashed and HW might be
@@ -3320,13 +3323,11 @@
vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr;
if (vsfr) {
- void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize);
- /* SFR isn't guaranteed to be NULL terminated
- * since SYS_ERROR indicates that Venus is in the
- * process of crashing.
- */
+ vsfr_size = vsfr->bufSize - sizeof(u32);
+ p = memchr(vsfr->rg_data, '\0', vsfr_size);
+ /* SFR isn't guaranteed to be NULL terminated */
if (p == NULL)
- vsfr->rg_data[vsfr->bufSize - 1] = '\0';
+ vsfr->rg_data[vsfr_size - 1] = '\0';
dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
vsfr->rg_data);
@@ -3440,8 +3441,6 @@
}
if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) {
- struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *)
- device->sfr.align_virtual_addr;
struct msm_vidc_cb_info info = {
.response_type = HAL_SYS_WATCHDOG_TIMEOUT,
.response.cmd = {
@@ -3449,9 +3448,7 @@
}
};
- if (vsfr)
- dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
- vsfr->rg_data);
+ print_sfr_message(device);
__dump_venus_debug_registers(device);
dprintk(VIDC_ERR, "Received watchdog timeout\n");
@@ -3479,7 +3476,7 @@
switch (info->response_type) {
case HAL_SYS_ERROR:
__dump_venus_debug_registers(device);
- __process_sys_error(device);
+ print_sfr_message(device);
break;
case HAL_SYS_RELEASE_RESOURCE_DONE:
dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");