aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Kirsch <jkirsch@codeaurora.org>2016-05-02 14:55:04 -0700
committerMenghui_Wu <menghui_wu@asus.com>2016-10-13 16:07:36 +0800
commit37eed8744900298258344f98f0f442b9a05d7386 (patch)
treec4e28813efd9568d0b0dc930d6d10a34bed9c8fe
parent101753b9905c645fb37d2a641b02668e0c464daf (diff)
drivers: soc: Add buffer overflow check for svc send requestandroid-wear-6.0.1_r0.93
Add buffer overflow check in voice_svc_send_req. CRs-fixed: 1010081 Change-Id: I4ae703334b0cf04f327b392bc9cd6febd4ad32f2 Signed-off-by: Josh Kirsch <jkirsch@codeaurora.org> Reviewed-on: http://mcrd1-22-pc.corpnet.asus/code-review/master/256473 Reviewed-by: jay_chuang <jay_chuang@asus.com> Tested-by: jay_chuang <jay_chuang@asus.com> Reviewed-by: Eric1 Lin <Eric1_Lin@asus.com>
-rw-r--r--drivers/soc/qcom/qdsp6v2/voice_svc.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c
index 3e51f97f4e37..d1ad102a069f 100644
--- a/drivers/soc/qcom/qdsp6v2/voice_svc.c
+++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -181,7 +181,8 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request,
int ret = 0;
void *apr_handle = NULL;
struct apr_data *aprdata = NULL;
- uint32_t user_payload_size = 0;
+ uint32_t user_payload_size;
+ uint32_t payload_size;
pr_debug("%s\n", __func__);
@@ -193,15 +194,19 @@ static int voice_svc_send_req(struct voice_svc_cmd_request *apr_request,
}
user_payload_size = apr_request->payload_size;
+ payload_size = sizeof(struct apr_data) + user_payload_size;
- aprdata = kmalloc(sizeof(struct apr_data) + user_payload_size,
- GFP_KERNEL);
-
- if (aprdata == NULL) {
- pr_err("%s: aprdata kmalloc failed.\n", __func__);
-
- ret = -ENOMEM;
+ if (payload_size <= user_payload_size) {
+ pr_err("%s: invalid payload size ( 0x%x ).\n",
+ __func__, user_payload_size);
+ ret = -EINVAL;
goto done;
+ } else {
+ aprdata = kmalloc(payload_size, GFP_KERNEL);
+ if (aprdata == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
}
voice_svc_update_hdr(apr_request, aprdata);
@@ -381,18 +386,31 @@ static ssize_t voice_svc_write(struct file *file, const char __user *buf,
switch (cmd) {
case MSG_REGISTER:
- ret = process_reg_cmd(
+ if (count >=
+ (sizeof(struct voice_svc_register) +
+ sizeof(*data))) {
+ ret = process_reg_cmd(
(struct voice_svc_register *)data->payload, prtd);
- if (!ret)
- ret = count;
-
+ if (!ret)
+ ret = count;
+ } else {
+ pr_err("%s: invalid payload size\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
break;
case MSG_REQUEST:
+ if (count >= (sizeof(struct voice_svc_cmd_request) +
+ sizeof(*data))) {
ret = voice_svc_send_req(
(struct voice_svc_cmd_request *)data->payload, prtd);
if (!ret)
ret = count;
-
+ } else {
+ pr_err("%s: invalid payload size\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
break;
default:
pr_debug("%s: Invalid command: %u\n", __func__, cmd);