diff options
author | Josh Kirsch <jkirsch@codeaurora.org> | 2016-05-02 14:55:04 -0700 |
---|---|---|
committer | Menghui_Wu <menghui_wu@asus.com> | 2016-10-13 16:07:36 +0800 |
commit | 37eed8744900298258344f98f0f442b9a05d7386 (patch) | |
tree | c4e28813efd9568d0b0dc930d6d10a34bed9c8fe | |
parent | 101753b9905c645fb37d2a641b02668e0c464daf (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.c | 46 |
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); |