From 75642c362c5341fbe45e2ead4ef50a55305c8e21 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Fri, 23 Mar 2018 08:57:33 +0800 Subject: [PATCH] ASoC: msm: check payload size before memory allocation Buffer from mixer ctl or ADSP is composed of payload size and actual payload. On a 32 bit platform, we could have an overflow if payload size is below UINT_MAX while payload size + sizeof(struct) is over UINT_MAX. Allocated memory size would be less than expected. Check payload size against limit before memory allocation. Change-Id: I0bf19ca7b8c93083177a21ad726122dc20f45551 Signed-off-by: Xiaojun Sang --- asoc/msm-compress-q6-v2.c | 4 ++-- asoc/msm-pcm-q6-v2.c | 4 ++-- asoc/msm-qti-pp-config.c | 5 +++-- asoc/msm-transcode-loopback-q6-v2.c | 6 +++--- dsp/q6asm.c | 7 +++++++ 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index b644df701123..7ba582a0c3aa 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -3681,8 +3681,8 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } - if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= - sizeof(ucontrol->value.bytes.data)) { + if (event_data->payload_len > sizeof(ucontrol->value.bytes.data) + - sizeof(struct msm_adsp_event_data)) { pr_err("%s param length=%d exceeds limit", __func__, event_data->payload_len); ret = -EINVAL; diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c index bbcbab35957c..b82128e7fabe 100644 --- a/asoc/msm-pcm-q6-v2.c +++ b/asoc/msm-pcm-q6-v2.c @@ -1138,8 +1138,8 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } - if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= - sizeof(ucontrol->value.bytes.data)) { + if (event_data->payload_len > sizeof(ucontrol->value.bytes.data) + - sizeof(struct msm_adsp_event_data)) { pr_err("%s param length=%d exceeds limit", __func__, event_data->payload_len); ret = -EINVAL; diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c index f210745fa69d..ccbc0b76004b 100644 --- a/asoc/msm-qti-pp-config.c +++ b/asoc/msm-qti-pp-config.c @@ -1025,8 +1025,9 @@ int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd, event_data = (struct msm_adsp_event_data *)payload; kctl->info(kctl, &kctl_info); - if (sizeof(struct msm_adsp_event_data) - + event_data->payload_len > kctl_info.count) { + + if (event_data->payload_len > + kctl_info.count - sizeof(struct msm_adsp_event_data)) { pr_err("%s: payload length exceeds limit of %u bytes.\n", __func__, kctl_info.count); ret = -EINVAL; diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c index 3c8e917f4278..3d4f8bf3ffbc 100644 --- a/asoc/msm-transcode-loopback-q6-v2.c +++ b/asoc/msm-transcode-loopback-q6-v2.c @@ -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 @@ -539,8 +539,8 @@ static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol, goto done; } - if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >= - sizeof(ucontrol->value.bytes.data)) { + if (event_data->payload_len > sizeof(ucontrol->value.bytes.data) + - sizeof(struct msm_adsp_event_data)) { pr_err("%s param length=%d exceeds limit", __func__, event_data->payload_len); ret = -EINVAL; diff --git a/dsp/q6asm.c b/dsp/q6asm.c index 5bfed89dcc61..55d82b7ce93d 100644 --- a/dsp/q6asm.c +++ b/dsp/q6asm.c @@ -2230,6 +2230,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) * package is composed of event type + size + actual payload */ payload_size = data->payload_size; + if (payload_size > UINT_MAX - sizeof(struct msm_adsp_event_data)) { + pr_err("%s: payload size = %d exceeds limit.\n", + __func__, payload_size); + spin_unlock(&(session[session_id].session_lock)); + return -EINVAL; + } + pp_event_package = kzalloc(payload_size + sizeof(struct msm_adsp_event_data), GFP_ATOMIC);