msm: cvp: Validate buffer config in HFI packet

Validates buffer configuration in HFI packet structure
before kernel driver maps them in IOMMU.

Change-Id: I7075cc2fdead7f46d52b174a3c45cd07a8ac24af
Signed-off-by: George Shen <sqiao@codeaurora.org>
This commit is contained in:
George Shen 2020-03-18 15:21:22 -07:00
commit e948d6199e
6 changed files with 71 additions and 33 deletions

View file

@ -2976,10 +2976,10 @@ static int __response_handler(struct iris_hfi_device *device)
print_msg_hdr(hdr);
rc = cvp_hfi_process_msg_packet(device->device_id,
(struct cvp_hal_msg_pkt_hdr *)raw_packet, info);
raw_packet, info);
if (rc) {
dprintk(CVP_WARN,
"Corrupt/unknown packet found, discarding\n");
"Corrupt/unknown packet found, discarding\n");
--packet_count;
continue;
} else if (info->response_type == HAL_NO_RESP) {
@ -3097,6 +3097,7 @@ err_no_work:
for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) &&
i < num_responses; ++i) {
struct msm_cvp_cb_info *r = &device->response_pkt[i];
void *rsp = (void *)&r->response;
if (!__core_in_valid_state(device)) {
dprintk(CVP_ERR,
@ -3105,7 +3106,7 @@ err_no_work:
}
dprintk(CVP_DBG, "Processing response %d of %d, type %d\n",
(i + 1), num_responses, r->response_type);
device->callback(r->response_type, &r->response);
device->callback(r->response_type, rsp);
}
/* We need re-enable the irq which was disabled in ISR handler */

View file

@ -201,8 +201,7 @@ struct msm_cvp_fw {
};
int cvp_hfi_process_msg_packet(u32 device_id,
struct cvp_hal_msg_pkt_hdr *msg_hdr,
struct msm_cvp_cb_info *info);
void *msg_hdr, struct msm_cvp_cb_info *info);
enum cvp_status cvp_hfi_process_sys_init_done_prop_read(
struct cvp_hfi_msg_sys_init_done_packet *pkt,

View file

@ -357,7 +357,8 @@ struct cvp_hfi_device {
typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd,
void *data);
typedef void (*msm_cvp_callback) (u32 response, void *callback);
typedef void (*msm_cvp_callback) (enum hal_command_response response,
void *callback);
struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type,
u32 device_id, struct msm_cvp_platform_resources *res,

View file

@ -116,9 +116,11 @@ static int hfi_process_session_error(u32 device_id,
}
static int hfi_process_event_notify(u32 device_id,
struct cvp_hfi_msg_event_notify_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_event_notify_packet *pkt =
(struct cvp_hfi_msg_event_notify_packet *)hdr;
dprintk(CVP_DBG, "Received: EVENT_NOTIFY\n");
if (pkt->size < sizeof(struct cvp_hfi_msg_event_notify_packet)) {
@ -147,9 +149,10 @@ static int hfi_process_event_notify(u32 device_id,
}
static int hfi_process_sys_init_done(u32 device_id,
struct cvp_hfi_msg_sys_init_done_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_sys_init_done_packet *pkt =
(struct cvp_hfi_msg_sys_init_done_packet *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
enum cvp_status status = CVP_ERR_NONE;
@ -224,9 +227,10 @@ enum cvp_status cvp_hfi_process_sys_init_done_prop_read(
}
static int hfi_process_session_init_done(u32 device_id,
struct cvp_hfi_msg_sys_session_init_done_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_sys_session_init_done_packet *pkt =
(struct cvp_hfi_msg_sys_session_init_done_packet *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
struct cvp_hal_session_init_done session_init_done = { {0} };
@ -251,9 +255,10 @@ static int hfi_process_session_init_done(u32 device_id,
return 0;
}
static int hfi_process_session_end_done(u32 device_id,
struct cvp_hfi_msg_sys_session_end_done_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_sys_session_end_done_packet *pkt =
(struct cvp_hfi_msg_sys_session_end_done_packet *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
dprintk(CVP_DBG, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id);
@ -276,9 +281,10 @@ static int hfi_process_session_end_done(u32 device_id,
}
static int hfi_process_session_abort_done(u32 device_id,
struct cvp_hfi_msg_sys_session_abort_done_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_sys_session_abort_done_packet *pkt =
(struct cvp_hfi_msg_sys_session_abort_done_packet *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
dprintk(CVP_DBG, "RECEIVED: SESSION_ABORT_DONE[%#x]\n",
@ -302,9 +308,10 @@ static int hfi_process_session_abort_done(u32 device_id,
}
static int hfi_process_session_set_buf_done(u32 device_id,
struct cvp_hfi_msg_session_hdr *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_session_hdr *pkt =
(struct cvp_hfi_msg_session_hdr *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
unsigned int pkt_size = get_msg_size();
@ -328,9 +335,10 @@ static int hfi_process_session_set_buf_done(u32 device_id,
}
static int hfi_process_session_flush_done(u32 device_id,
struct cvp_hfi_msg_sys_session_flush_done_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_sys_session_flush_done_packet *pkt =
(struct cvp_hfi_msg_sys_session_flush_done_packet *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
dprintk(CVP_DBG, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n",
@ -354,9 +362,10 @@ static int hfi_process_session_flush_done(u32 device_id,
}
static int hfi_process_session_rel_buf_done(u32 device_id,
struct cvp_hfi_msg_session_hdr *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_session_hdr *pkt =
(struct cvp_hfi_msg_session_hdr *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
unsigned int pkt_size = get_msg_size();
@ -380,9 +389,10 @@ static int hfi_process_session_rel_buf_done(u32 device_id,
}
static int hfi_process_session_cvp_operation_config(u32 device_id,
struct cvp_hfi_msg_session_op_cfg_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_session_op_cfg_packet *pkt =
(struct cvp_hfi_msg_session_op_cfg_packet *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0};
int signal;
unsigned int conf_id, session_id, error_type;
@ -467,9 +477,10 @@ retry:
}
static int hfi_process_session_cvp_msg(u32 device_id,
struct cvp_hfi_msg_session_hdr *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_session_hdr *pkt =
(struct cvp_hfi_msg_session_hdr *)hdr;
struct cvp_session_msg *sess_msg;
struct msm_cvp_inst *inst = NULL;
struct msm_cvp_core *core;
@ -563,9 +574,10 @@ static void hfi_process_sys_get_prop_image_version(
}
static int hfi_process_sys_property_info(u32 device_id,
struct cvp_hfi_msg_sys_property_info_packet *pkt,
struct msm_cvp_cb_info *info)
void *hdr, struct msm_cvp_cb_info *info)
{
struct cvp_hfi_msg_sys_property_info_packet *pkt =
(struct cvp_hfi_msg_sys_property_info_packet *)hdr;
if (!pkt) {
dprintk(CVP_ERR, "%s: invalid param\n", __func__);
return -EINVAL;
@ -596,12 +608,12 @@ static int hfi_process_sys_property_info(u32 device_id,
}
int cvp_hfi_process_msg_packet(u32 device_id,
struct cvp_hal_msg_pkt_hdr *msg_hdr,
struct msm_cvp_cb_info *info)
int cvp_hfi_process_msg_packet(u32 device_id, void *hdr,
struct msm_cvp_cb_info *info)
{
typedef int (*pkt_func_def)(u32, void *, struct msm_cvp_cb_info *info);
pkt_func_def pkt_func = NULL;
struct cvp_hal_msg_pkt_hdr *msg_hdr = (struct cvp_hal_msg_pkt_hdr *)hdr;
if (!info || !msg_hdr || msg_hdr->size < CVP_IFACEQ_MIN_PKT_SIZE) {
dprintk(CVP_ERR, "%s: bad packet/packet size\n",
@ -659,5 +671,5 @@ int cvp_hfi_process_msg_packet(u32 device_id,
}
return pkt_func ?
pkt_func(device_id, (void *)msg_hdr, info) : -ENOTSUPP;
pkt_func(device_id, hdr, info) : -ENOTSUPP;
}

View file

@ -204,7 +204,10 @@ static int msm_cvp_session_process_hfi(
offset = in_offset;
buf_num = in_buf_num;
}
if (!is_buf_param_valid(buf_num, offset)) {
dprintk(CVP_ERR, "Incorrect buffer num and offset in cmd\n");
return -EINVAL;
}
pkt_type = in_pkt->pkt_data[1];
if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS)
rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num);
@ -741,6 +744,10 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
buf_num = cvp_hfi_defs[idx].buf_num;
}
if (!is_buf_param_valid(buf_num, offset)) {
dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n");
return -EINVAL;
}
rc = msm_cvp_map_frame(inst, (struct cvp_kmd_hfi_packet *)pkt, offset,
buf_num);
if (rc)

View file

@ -11,6 +11,24 @@
#include "msm_cvp_clocks.h"
#include "msm_cvp_debug.h"
#include "msm_cvp_dsp.h"
static inline bool is_buf_param_valid(u32 buf_num, u32 offset)
{
int max_buf_num;
max_buf_num = sizeof(struct cvp_kmd_hfi_packet) /
sizeof(struct cvp_buf_type);
if (buf_num > max_buf_num)
return false;
if ((offset + buf_num * sizeof(struct cvp_buf_type)) >
sizeof(struct cvp_kmd_hfi_packet))
return false;
return true;
}
int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg);
int msm_cvp_session_init(struct msm_cvp_inst *inst);
int msm_cvp_session_deinit(struct msm_cvp_inst *inst);