msm: cpp: Validate frame message before manipulating it

CPP frame message is used to send all frame data
to Microcontroller. It is sent every frame. CPP kernel
driver has to add information to it before transfer it.
The message has to be validated before manipulations.
If it is not valid the message and corresponding frame
are discarded.
Change-Id: Ib5b9b5d2e1886d3d671966b693ce212d58e34041
Signed-off-by: Manish Poddar <mpoddar@codeaurora.org>
This commit is contained in:
Manish Poddar
2014-07-11 15:21:01 +05:30
parent 06694b4ea4
commit f4e2f2d4ef
3 changed files with 50 additions and 15 deletions
@@ -56,6 +56,16 @@
#define MSM_CPP_NOMINAL_CLOCK 266670000
#define MSM_CPP_TURBO_CLOCK 320000000
#define CPP_FW_VERSION_1_2_0 0x10020000
#define CPP_FW_VERSION_1_4_0 0x10040000
#define CPP_FW_VERSION_1_6_0 0x10060000
#define CPP_FW_VERSION_1_8_0 0x10080000
/* stripe information offsets in frame command */
#define STRIPE_BASE_FW_1_2_0 130
#define STRIPE_BASE_FW_1_4_0 140
#define STRIPE_BASE_FW_1_6_0 464
struct msm_cpp_timer_data_t {
struct cpp_device *cpp_dev;
struct msm_cpp_frame_info_t *processed_frame;
@@ -918,7 +928,8 @@ static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_CMD);
msm_cpp_poll(cpp_dev->base, 0x2);
msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_FW_VER);
pr_info("CPP FW Version: 0x%x\n", msm_cpp_read(cpp_dev->base));
cpp_dev->fw_version = msm_cpp_read(cpp_dev->base);
pr_info("CPP FW Version: 0x%08x\n", cpp_dev->fw_version);
msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER);
/*Disable MC clock*/
@@ -1287,9 +1298,8 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
struct msm_cpp_frame_info_t *u_frame_info =
(struct msm_cpp_frame_info_t *)ioctl_ptr->ioctl_ptr;
int32_t status = 0;
uint8_t fw_version_1_2_x = 0;
int in_fd;
int32_t stripe_base = 0;
int i = 0;
if (!new_frame) {
pr_err("Insufficient memory. return\n");
@@ -1330,7 +1340,16 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
}
new_frame->cpp_cmd_msg = cpp_frame_msg;
if (cpp_frame_msg == NULL ||
(new_frame->msg_len < MSM_CPP_MIN_FRAME_LENGTH)) {
pr_err("%s %d Length is not correct or frame message is missing\n",
__func__, __LINE__);
return -EINVAL;
}
if (cpp_frame_msg[new_frame->msg_len - 1] != MSM_CPP_MSG_ID_TRAILER) {
pr_err("%s %d Invalid frame message\n", __func__, __LINE__);
return -EINVAL;
}
in_phyaddr = msm_cpp_fetch_buffer_info(cpp_dev,
&new_frame->input_buffer_info,
((new_frame->input_buffer_info.identity >> 16) & 0xFFFF),
@@ -1404,22 +1423,36 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev,
((cpp_frame_msg[12] >> 10) & 0x3FF) +
(cpp_frame_msg[12] & 0x3FF);
fw_version_1_2_x = 0;
if ((cpp_dev->hw_info.cpp_hw_version == CPP_HW_VERSION_1_1_0) ||
(cpp_dev->hw_info.cpp_hw_version == CPP_HW_VERSION_1_1_1) ||
(cpp_dev->hw_info.cpp_hw_version == CPP_HW_VERSION_2_0_0))
fw_version_1_2_x = 2;
if ((cpp_dev->fw_version & 0xffff0000) ==
CPP_FW_VERSION_1_2_0) {
stripe_base = STRIPE_BASE_FW_1_2_0;
} else if ((cpp_dev->fw_version & 0xffff0000) ==
CPP_FW_VERSION_1_4_0) {
stripe_base = STRIPE_BASE_FW_1_4_0;
} else if ((cpp_dev->fw_version & 0xffff0000) ==
CPP_FW_VERSION_1_6_0) {
stripe_base = STRIPE_BASE_FW_1_6_0;
} else {
pr_err("invalid fw version %08x", cpp_dev->fw_version);
}
if ((stripe_base + num_stripes*27 + 1) != new_frame->msg_len) {
pr_err("Invalid frame message\n");
rc = -EINVAL;
goto ERROR3;
}
for (i = 0; i < num_stripes; i++) {
cpp_frame_msg[(133 + fw_version_1_2_x) + i * 27] +=
cpp_frame_msg[stripe_base + 5 + i*27] +=
(uint32_t) in_phyaddr;
cpp_frame_msg[(139 + fw_version_1_2_x) + i * 27] +=
cpp_frame_msg[stripe_base + 11 + i * 27] +=
(uint32_t) out_phyaddr0;
cpp_frame_msg[(140 + fw_version_1_2_x) + i * 27] +=
cpp_frame_msg[stripe_base + 12 + i * 27] +=
(uint32_t) out_phyaddr1;
cpp_frame_msg[(141 + fw_version_1_2_x) + i * 27] +=
cpp_frame_msg[stripe_base + 13 + i * 27] +=
(uint32_t) out_phyaddr0;
cpp_frame_msg[(142 + fw_version_1_2_x) + i * 27] +=
cpp_frame_msg[stripe_base + 14 + i * 27] +=
(uint32_t) out_phyaddr1;
}
@@ -189,6 +189,7 @@ struct cpp_device {
char *fw_name_bin;
struct workqueue_struct *timer_wq;
struct msm_cpp_work_t *work;
uint32_t fw_version;
uint8_t stream_cnt;
uint8_t timeout_trial_cnt;
+2 -1
View File
@@ -13,7 +13,8 @@
#define MAX_NUM_CPP_STRIPS 8
#define MSM_CPP_MAX_NUM_PLANES 3
#define MSM_CPP_MAX_FRAME_LENGTH 1024
#define MSM_CPP_MIN_FRAME_LENGTH 13
#define MSM_CPP_MAX_FRAME_LENGTH 2048
#define MSM_CPP_MAX_FW_NAME_LEN 32
#define MAX_FREQ_TBL 10