DivestOS/Patches/Linux_CVEs/CVE-2014-9788/ANY/0.patch
2017-10-29 22:14:37 -04:00

195 lines
5.5 KiB
Diff

From 73bfc22aa70cc0b7e6709381125a0a42aa72a4f2 Mon Sep 17 00:00:00 2001
From: Shiv Maliyappanahalli <smaliyap@codeaurora.org>
Date: Wed, 2 Oct 2013 17:00:30 -0700
Subject: ASoC: msm: qdsp6v2: Fix buffer overflow in voice driver
Userspace registers calibration data with acdb driver
through ioctls. Voice driver registers the calibration
data with CVD by querying acdb data from acdb driver and
copies the calibration data in apr message.
The size of the calibration data can be controlled by userspace
and can result in buffer overflow if the calibration size is
greater than the destination buffer size.
Reject acdb data if the size is greater than the size of
destination buffer.
CRs-Fixed: 548872
Change-Id: I4cd23a38c90b745226ddbc28656c82ff7c10432b
Signed-off-by: Shiv Maliyappanahalli <smaliyap@codeaurora.org>
---
sound/soc/msm/qdsp6/q6voice.c | 9 ++++---
sound/soc/msm/qdsp6v2/q6voice.c | 53 ++++++++++++++++++++++++++++++++++-------
2 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 0e53c64..7294350 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -1519,7 +1519,8 @@ static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
/* get the cvs cal data */
get_all_vocstrm_cal(&cal_block);
- if (cal_block.cal_size == 0)
+ if (cal_block.cal_size == 0 ||
+ cal_block.cal_size > CVS_CAL_SIZE)
goto fail;
if (v == NULL) {
@@ -1928,7 +1929,8 @@ static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
/* get the cvp cal data */
get_all_vocproc_cal(&cal_block);
- if (cal_block.cal_size == 0)
+ if (cal_block.cal_size == 0 ||
+ cal_block.cal_size > CVP_CAL_SIZE)
goto fail;
if (v == NULL) {
@@ -2063,7 +2065,8 @@ static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
get_all_vocvol_cal(&vol_block);
get_all_vocproc_cal(&voc_block);
- if (vol_block.cal_size == 0)
+ if (vol_block.cal_size == 0 ||
+ vol_block.cal_size > CVP_CAL_SIZE)
goto fail;
if (v == NULL) {
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 079cc4d..622fae1 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -1955,20 +1955,22 @@ static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
if (!common.apr_q6_cvs) {
pr_err("%s: apr_cvs is NULL\n", __func__);
- ret = -EPERM;
+ ret = -EINVAL;
goto done;
}
if (!common.cal_mem_handle) {
pr_err("%s: Cal mem handle is NULL\n", __func__);
- ret = -EPERM;
+
+ ret = -EINVAL;
goto done;
}
get_vocstrm_cal(&cal_block);
if (cal_block.cal_size == 0) {
pr_err("%s: CVS cal size is 0\n", __func__);
- ret = -EPERM;
+
+ ret = -EINVAL;
goto done;
}
@@ -1989,6 +1991,15 @@ static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
/* Get the column info corresponding to CVS cal from ACDB. */
get_voice_col_data(VOCSTRM_CAL, &cal_block);
+ if (cal_block.cal_size == 0 ||
+ cal_block.cal_size >
+ sizeof(cvs_reg_cal_cmd.cvs_cal_data.column_info)) {
+ pr_err("%s: Invalid VOCSTRM_CAL size %d\n",
+ __func__, cal_block.cal_size);
+
+ ret = -EINVAL;
+ goto done;
+ }
memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0],
(void *) cal_block.cal_kvaddr,
cal_block.cal_size);
@@ -2227,20 +2238,22 @@ static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
if (!common.apr_q6_cvp) {
pr_err("%s: apr_cvp is NULL\n", __func__);
- ret = -EPERM;
+ ret = -EINVAL;
goto done;
}
if (!common.cal_mem_handle) {
pr_err("%s: Cal mem handle is NULL\n", __func__);
- ret = -EPERM;
+
+ ret = -EINVAL;
goto done;
}
get_vocproc_cal(&cal_block);
if (cal_block.cal_size == 0) {
pr_err("%s: CVP cal size is 0\n", __func__);
- ret = -EPERM;
+
+ ret = -EINVAL;
goto done;
}
@@ -2261,6 +2274,16 @@ static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
/* Get the column info corresponding to CVP cal from ACDB. */
get_voice_col_data(VOCPROC_CAL, &cal_block);
+ if (cal_block.cal_size == 0 ||
+ cal_block.cal_size >
+ sizeof(cvp_reg_cal_cmd.cvp_cal_data.column_info)) {
+ pr_err("%s: Invalid VOCPROC_CAL size %d\n",
+ __func__, cal_block.cal_size);
+
+ ret = -EINVAL;
+ goto done;
+ }
+
memcpy(&cvp_reg_cal_cmd.cvp_cal_data.column_info[0],
(void *) cal_block.cal_kvaddr,
cal_block.cal_size);
@@ -2363,20 +2386,22 @@ static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
if (!common.apr_q6_cvp) {
pr_err("%s: apr_cvp is NULL\n", __func__);
- ret = -EPERM;
+ ret = -EINVAL;
goto done;
}
if (!common.cal_mem_handle) {
pr_err("%s: Cal mem handle is NULL\n", __func__);
- ret = -EPERM;
+
+ ret = -EINVAL;
goto done;
}
get_vocvol_cal(&cal_block);
if (cal_block.cal_size == 0) {
pr_err("%s: CVP vol cal size is 0\n", __func__);
- ret = -EPERM;
+
+ ret = -EINVAL;
goto done;
}
@@ -2399,6 +2424,16 @@ static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
/* Get the column info corresponding to CVP volume cal from ACDB. */
get_voice_col_data(VOCVOL_CAL, &cal_block);
+ if (cal_block.cal_size == 0 ||
+ cal_block.cal_size >
+ sizeof(cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info)) {
+ pr_err("%s: Invalid VOCVOL_CAL size %d\n",
+ __func__, cal_block.cal_size);
+
+ ret = -EINVAL;
+ goto done;
+ }
+
memcpy(&cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info[0],
(void *) cal_block.cal_kvaddr,
cal_block.cal_size);
--
cgit v1.1