DivestOS/Patches/Linux_CVEs/CVE-2014-9889/ANY/0001.patch
2017-11-07 17:32:46 -05:00

156 lines
5.6 KiB
Diff

From f4e2f2d4ef58c88340774099dff3324ec8baa24a Mon Sep 17 00:00:00 2001
From: Manish Poddar <mpoddar@codeaurora.org>
Date: Thu, 10 Jul 2014 19:43:31 +0530
Subject: 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>
---
.../platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 61 +++++++++++++++++-----
.../platform/msm/camera_v2/pproc/cpp/msm_cpp.h | 1 +
include/media/msmb_pproc.h | 3 +-
3 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index d3a848a..253cbed 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -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;
}
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
index bd73ab2..af1af2d 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
@@ -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;
diff --git a/include/media/msmb_pproc.h b/include/media/msmb_pproc.h
index 59dcca9..f5a53a8 100644
--- a/include/media/msmb_pproc.h
+++ b/include/media/msmb_pproc.h
@@ -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
--
cgit v1.1