From ba4427e9ef9cc453061c9f16b3ada12f34bc060c Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Wed, 22 May 2019 13:01:02 +0530 Subject: [PATCH] msm: vidc: add additional check to avoid out of bound access pkt->msg_size can be corrupted and that leads to OOB access. So added additional conditional check to avoid OOB access in debug queue packet handling. Change-Id: I360812c40369ecef2dd99464d400661bc785074b Signed-off-by: Govindaraj Rajagopal Signed-off-by: Sanjay Singh --- drivers/media/platform/msm/vidc/venus_hfi.c | 39 +++++++++++++++++-- .../media/platform/msm/vidc/vidc_hfi_helper.h | 7 +++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index f6180b848c7f..ff994ed6c12b 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -39,6 +39,7 @@ #define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 +#define MIN_PAYLOAD_SIZE 3 static struct hal_device_data hal_ctxt; @@ -3457,23 +3458,55 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet) log_level = VIDC_ERR; } +#define SKIP_INVALID_PKT(pkt_size, payload_size, pkt_hdr_size) ({ \ + if (pkt_size < pkt_hdr_size || \ + payload_size < MIN_PAYLOAD_SIZE || \ + payload_size > \ + (pkt_size - pkt_hdr_size + sizeof(u8))) { \ + dprintk(VIDC_ERR, \ + "%s: invalid msg size - %d\n", \ + __func__, pkt->msg_size); \ + continue; \ + } \ + }) + while (!__iface_dbgq_read(device, packet)) { - struct hfi_msg_sys_coverage_packet *pkt = - (struct hfi_msg_sys_coverage_packet *) packet; + struct hfi_packet_header *pkt = + (struct hfi_packet_header *) packet; + + if (pkt->size < sizeof(struct hfi_packet_header)) { + dprintk(VIDC_ERR, "Invalid pkt size - %s\n", + __func__); + continue; + } + if (pkt->packet_type == HFI_MSG_SYS_COV) { + struct hfi_msg_sys_coverage_packet *pkt = + (struct hfi_msg_sys_coverage_packet *) packet; int stm_size = 0; + + SKIP_INVALID_PKT(pkt->size, + pkt->msg_size, sizeof(*pkt)); + stm_size = stm_log_inv_ts(0, 0, pkt->rg_msg_data, pkt->msg_size); if (stm_size == 0) dprintk(VIDC_ERR, "In %s, stm_log returned size of 0\n", __func__); - } else { + + } else if (pkt->packet_type == HFI_MSG_SYS_DEBUG) { struct hfi_msg_sys_debug_packet *pkt = (struct hfi_msg_sys_debug_packet *) packet; + + SKIP_INVALID_PKT(pkt->size, + pkt->msg_size, sizeof(*pkt)); + + pkt->rg_msg_data[pkt->msg_size-1] = '\0'; dprintk(log_level, "%s", pkt->rg_msg_data); } } +#undef SKIP_INVALID_PKT if (local_packet) kfree(packet); diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index 1218f0a86bc4..3709ad9fc658 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 2019, 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 @@ -976,6 +976,11 @@ struct vidc_hal_session_cmd_pkt { u32 session_id; }; +struct hfi_packet_header { + u32 size; + u32 packet_type; +}; + struct hfi_cmd_sys_init_packet { u32 size; u32 packet_type;