summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSurajit Podder <spodder@codeaurora.org>2017-05-09 18:48:05 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-05-31 20:29:15 -0700
commitb9109a04fe17eead3a0ef1e5730b174301593515 (patch)
tree1e1f67e22a044dd8c5d1d6d8c65b123308034801
parenta5706c4fdac1a427fac7b30a49912a1d9d148cb9 (diff)
msm: vidc: Copy user buffers to kernel memory before access
trigger_ssr_write directly accesses user buffer, which can lead to crash. Copy user buffer to kernel memory before access. Also, set initial value for ssr_trigger_val, and use kstrtoul instead of sscanf, with proper checking of return code. Change-Id: I94b1c14a8ae4628cb6ac0ee7f3bd38b0c79f088b Signed-off-by: Surajit Podder <spodder@codeaurora.org>
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_debug.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index a9b367d6fe93..885e61f8bf01 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -12,6 +12,7 @@
*/
#define CREATE_TRACE_POINTS
+#define MAX_SSR_STRING_LEN 10
#include "msm_vidc_debug.h"
#include "vidc_hfi_api.h"
@@ -136,17 +137,33 @@ static int trigger_ssr_open(struct inode *inode, struct file *file)
static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos) {
- u32 ssr_trigger_val;
- int rc;
+ unsigned long ssr_trigger_val = 0;
+ int rc = 0;
struct msm_vidc_core *core = filp->private_data;
- rc = sscanf(buf, "%d", &ssr_trigger_val);
- if (rc < 0) {
+ size_t size = MAX_SSR_STRING_LEN;
+ char kbuf[MAX_SSR_STRING_LEN + 1] = {0};
+
+ if (!count)
+ goto exit;
+
+ if (count < size)
+ size = count;
+
+ if (copy_from_user(kbuf, buf, size)) {
+ dprintk(VIDC_WARN, "%s User memory fault\n", __func__);
+ rc = -EFAULT;
+ goto exit;
+ }
+
+ rc = kstrtoul(kbuf, 0, &ssr_trigger_val);
+ if (rc) {
dprintk(VIDC_WARN, "returning error err %d\n", rc);
rc = -EINVAL;
} else {
msm_vidc_trigger_ssr(core, ssr_trigger_val);
rc = count;
}
+exit:
return rc;
}