DivestOS/Patches/Linux_CVEs/CVE-2017-8244/4.4/0003.patch
2017-11-07 17:32:46 -05:00

166 lines
5.5 KiB
Diff

From fe3bdd12315656347d1bca82d920b3df1a2b0e8a Mon Sep 17 00:00:00 2001
From: Abdulla Anam <abdullahanam@codeaurora.org>
Date: Wed, 22 Mar 2017 14:00:10 +0530
Subject: msm: vidc: Protect debug_buffer access in info_read with lock
Serialize core_info_read & inst_info_read with lock so that
multiple concurrent threads do not cause the write to
overflow. Also have the bound check to avoid overflow in
write_str function..
Change-Id: Ia18a4b94cafd69af1d367861f2499fc202f18e9f
Signed-off-by: Abdulla Anam <abdullahanam@codeaurora.org>
---
drivers/media/platform/msm/vidc/msm_v4l2_vidc.c | 3 +++
drivers/media/platform/msm/vidc/msm_vidc_debug.c | 33 +++++++++++++++++++++---
drivers/media/platform/msm/vidc/msm_vidc_debug.h | 1 +
3 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index a632797..a8dc1d0 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -766,6 +766,8 @@ static int __init msm_vidc_init(void)
if (rc) {
dprintk(VIDC_ERR,
"Failed to register platform driver\n");
+ msm_vidc_debugfs_deinit_drv();
+ debugfs_remove_recursive(vidc_driver->debugfs_root);
kfree(vidc_driver);
vidc_driver = NULL;
}
@@ -776,6 +778,7 @@ static int __init msm_vidc_init(void)
static void __exit msm_vidc_exit(void)
{
platform_driver_unregister(&msm_vidc_driver);
+ msm_vidc_debugfs_deinit_drv();
debugfs_remove_recursive(vidc_driver->debugfs_root);
mutex_destroy(&vidc_driver->lock);
kfree(vidc_driver);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index 1248a1c..a9b367d 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -38,6 +38,7 @@ bool msm_vidc_debug_timeout = false;
#define MAX_DBG_BUF_SIZE 4096
struct debug_buffer {
+ struct mutex lock;
char ptr[MAX_DBG_BUF_SIZE];
char *curr;
u32 filled_size;
@@ -64,8 +65,12 @@ static u32 write_str(struct debug_buffer *buffer, const char *fmt, ...)
{
va_list args;
u32 size;
+
+ char *curr = buffer->curr;
+ char *end = buffer->ptr + MAX_DBG_BUF_SIZE;
+
va_start(args, fmt);
- size = vscnprintf(buffer->curr, MAX_DBG_BUF_SIZE - 1, fmt, args);
+ size = vscnprintf(curr, end - curr, fmt, args);
va_end(args);
buffer->curr += size;
buffer->filled_size += size;
@@ -79,12 +84,15 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
struct hfi_device *hdev;
struct hal_fw_info fw_info = { {0} };
int i = 0, rc = 0;
+ ssize_t len = 0;
if (!core || !core->device) {
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core);
return 0;
}
hdev = core->device;
+
+ mutex_lock(&dbg_buf.lock);
INIT_DBG_BUF(dbg_buf);
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "CORE %d: %pK\n", core->id, core);
@@ -108,8 +116,11 @@ err_fw_info:
completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
"pending" : "done");
}
- return simple_read_from_buffer(buf, count, ppos,
+ len = simple_read_from_buffer(buf, count, ppos,
dbg_buf.ptr, dbg_buf.filled_size);
+
+ mutex_unlock(&dbg_buf.lock);
+ return len;
}
static const struct file_operations core_info_fops = {
@@ -147,7 +158,10 @@ static const struct file_operations ssr_fops = {
struct dentry *msm_vidc_debugfs_init_drv(void)
{
bool ok = false;
- struct dentry *dir = debugfs_create_dir("msm_vidc", NULL);
+ struct dentry *dir = NULL;
+
+ mutex_init(&dbg_buf.lock);
+ dir = debugfs_create_dir("msm_vidc", NULL);
if (IS_ERR_OR_NULL(dir)) {
dir = NULL;
goto failed_create_dir;
@@ -216,6 +230,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
goto failed_create_dir;
}
+
if (!debugfs_create_file("info", S_IRUGO, dir, core, &core_info_fops)) {
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
goto failed_create_dir;
@@ -269,11 +284,14 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
{
struct msm_vidc_inst *inst = file->private_data;
int i, j;
+ ssize_t len = 0;
if (!inst) {
dprintk(VIDC_ERR, "Invalid params, inst %pK\n", inst);
return 0;
}
+
+ mutex_lock(&dbg_buf.lock);
INIT_DBG_BUF(dbg_buf);
write_str(&dbg_buf, "===============================\n");
write_str(&dbg_buf, "INSTANCE: %pK (%s)\n", inst,
@@ -331,8 +349,10 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
publish_unreleased_reference(inst);
- return simple_read_from_buffer(buf, count, ppos,
+ len = simple_read_from_buffer(buf, count, ppos,
dbg_buf.ptr, dbg_buf.filled_size);
+ mutex_unlock(&dbg_buf.lock);
+ return len;
}
static const struct file_operations inst_info_fops = {
@@ -413,3 +433,8 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
}
}
+void msm_vidc_debugfs_deinit_drv(void)
+{
+ mutex_destroy(&dbg_buf.lock);
+}
+
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index 39ac627..853ce4b 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -126,6 +126,7 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
struct dentry *parent);
void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
enum msm_vidc_debugfs_event e);
+void msm_vidc_debugfs_deinit_drv(void);
static inline void tic(struct msm_vidc_inst *i, enum profiling_points p,
char *b)
--
cgit v1.1