asoc: msm: add check for integer overflow

Add check for integer overflow of user
supplied data for ADSP stream command.

CRs-Fixed: 2173850
Change-Id: Ic70093e890b7a6dd07529d77d10fff003282a8ea
Signed-off-by: Aditya Bavanari <abavanar@codeaurora.org>
This commit is contained in:
Aditya Bavanari 2018-02-23 13:15:19 +05:30
parent c2c950b468
commit 893f3cf2fb
4 changed files with 49 additions and 5 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 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
@ -3701,6 +3701,7 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct msm_compr_audio *prtd;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
uint64_t actual_payload_len = 0;
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received invalid fe_id %lu\n",
@ -3738,6 +3739,16 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
actual_payload_len = sizeof(struct msm_adsp_event_data) +
event_data->payload_len;
if (actual_payload_len >= U32_MAX) {
pr_err("%s payload length 0x%X exceeds limit",
__func__, event_data->payload_len);
ret = -EINVAL;
goto done;
}
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 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
@ -52,6 +52,7 @@ static struct audio_locks the_locks;
static const DECLARE_TLV_DB_LINEAR(msm_pcm_vol_gain, 0,
PCM_MASTER_VOL_MAX_STEPS);
struct snd_msm {
struct snd_card *card;
struct snd_pcm *pcm;
@ -1084,6 +1085,7 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct msm_audio *prtd;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
uint64_t actual_payload_len = 0;
if (!pdata) {
pr_err("%s pdata is NULL\n", __func__);
@ -1120,6 +1122,15 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
actual_payload_len = sizeof(struct msm_adsp_event_data) +
event_data->payload_len;
if (actual_payload_len >= U32_MAX) {
pr_err("%s payload length 0x%X exceeds limit",
__func__, event_data->payload_len);
ret = -EINVAL;
goto done;
}
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, 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
@ -645,6 +645,7 @@ static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct msm_transcode_loopback *prtd;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
uint64_t actual_payload_len = 0;
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received invalid fe_id %lu\n",
@ -682,6 +683,16 @@ static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
actual_payload_len = sizeof(struct msm_adsp_event_data) +
event_data->payload_len;
if (actual_payload_len >= U32_MAX) {
pr_err("%s payload length 0x%X exceeds limit",
__func__, event_data->payload_len);
ret = -EINVAL;
goto done;
}
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",

View file

@ -47,6 +47,7 @@
#define FALSE 0x00
#define SESSION_MAX 9
#define ASM_MAX_CHANNELS 8
enum {
ASM_TOPOLOGY_CAL = 0,
ASM_CUSTOM_TOP_CAL,
@ -1159,7 +1160,9 @@ int q6asm_send_stream_cmd(struct audio_client *ac,
{
char *asm_params = NULL;
struct apr_hdr hdr;
int sz, rc;
int rc;
uint32_t sz = 0;
uint64_t actual_sz = 0;
if (!data || !ac) {
pr_err("%s: %s is NULL\n", __func__,
@ -1176,7 +1179,15 @@ int q6asm_send_stream_cmd(struct audio_client *ac,
goto done;
}
sz = sizeof(struct apr_hdr) + data->payload_len;
actual_sz = sizeof(struct apr_hdr) + data->payload_len;
if (actual_sz > U32_MAX) {
pr_err("%s: payload size 0x%X exceeds limit\n",
__func__, data->payload_len);
rc = -EINVAL;
goto done;
}
sz = (uint32_t)actual_sz;
asm_params = kzalloc(sz, GFP_KERNEL);
if (!asm_params) {
rc = -ENOMEM;