mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-22 06:04:57 -05:00
179 lines
5.6 KiB
Diff
179 lines
5.6 KiB
Diff
|
From 80be0e249c906704085d13d4ae446f73913fc225 Mon Sep 17 00:00:00 2001
|
||
|
From: Baruch Eruchimovitch <baruche@codeaurora.org>
|
||
|
Date: Mon, 14 Oct 2013 15:49:41 +0300
|
||
|
Subject: msm: ultrasound: add verifications of some input parameters
|
||
|
|
||
|
Some security vulnerabilities were found.
|
||
|
To fix them, additional verifications of some input parameters
|
||
|
are required.
|
||
|
|
||
|
CRs-Fixed: 554575, 554560, 555030
|
||
|
Change-Id: Ie87a433bcda89c3e462cfd511c168e8306056020
|
||
|
Signed-off-by: Baruch Eruchimovitch <baruche@codeaurora.org>
|
||
|
---
|
||
|
arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c | 82 ++++++++++++++++++------------
|
||
|
1 file changed, 49 insertions(+), 33 deletions(-)
|
||
|
|
||
|
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
|
||
|
index 1ea213a..01fcfd9 100644
|
||
|
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
|
||
|
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
|
||
|
@@ -51,6 +51,11 @@
|
||
|
#define Y_IND 1
|
||
|
#define Z_IND 2
|
||
|
|
||
|
+/* Shared memory limits */
|
||
|
+/* max_buf_size = (port_size(65535*2) * port_num(8) * group_size(3) */
|
||
|
+#define USF_MAX_BUF_SIZE 3145680
|
||
|
+#define USF_MAX_BUF_NUM 32
|
||
|
+
|
||
|
/* Place for opreation result, received from QDSP6 */
|
||
|
#define APR_RESULT_IND 1
|
||
|
|
||
|
@@ -436,6 +441,15 @@ static int config_xx(struct usf_xx_type *usf_xx, struct us_xx_info_type *config)
|
||
|
(config == NULL))
|
||
|
return -EINVAL;
|
||
|
|
||
|
+ if ((config->buf_size == 0) ||
|
||
|
+ (config->buf_size > USF_MAX_BUF_SIZE) ||
|
||
|
+ (config->buf_num == 0) ||
|
||
|
+ (config->buf_num > USF_MAX_BUF_NUM)) {
|
||
|
+ pr_err("%s: wrong params: buf_size=%d; buf_num=%d\n",
|
||
|
+ __func__, config->buf_size, config->buf_num);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
data_map_size = sizeof(usf_xx->encdec_cfg.cfg_common.data_map);
|
||
|
min_map_size = min(data_map_size, config->port_cnt);
|
||
|
|
||
|
@@ -748,6 +762,7 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||
|
{
|
||
|
uint32_t timeout = 0;
|
||
|
struct us_detect_info_type detect_info;
|
||
|
+ struct usm_session_cmd_detect_info *p_allocated_memory = NULL;
|
||
|
struct usm_session_cmd_detect_info usm_detect_info;
|
||
|
struct usm_session_cmd_detect_info *p_usm_detect_info =
|
||
|
&usm_detect_info;
|
||
|
@@ -774,12 +789,13 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||
|
uint8_t *p_data = NULL;
|
||
|
|
||
|
detect_info_size += detect_info.params_data_size;
|
||
|
- p_usm_detect_info = kzalloc(detect_info_size, GFP_KERNEL);
|
||
|
- if (p_usm_detect_info == NULL) {
|
||
|
+ p_allocated_memory = kzalloc(detect_info_size, GFP_KERNEL);
|
||
|
+ if (p_allocated_memory == NULL) {
|
||
|
pr_err("%s: detect_info[%d] allocation failed\n",
|
||
|
__func__, detect_info_size);
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
+ p_usm_detect_info = p_allocated_memory;
|
||
|
p_data = (uint8_t *)p_usm_detect_info +
|
||
|
sizeof(struct usm_session_cmd_detect_info);
|
||
|
|
||
|
@@ -789,7 +805,7 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||
|
if (rc) {
|
||
|
pr_err("%s: copy params from user; rc=%d\n",
|
||
|
__func__, rc);
|
||
|
- kfree(p_usm_detect_info);
|
||
|
+ kfree(p_allocated_memory);
|
||
|
return -EFAULT;
|
||
|
}
|
||
|
p_usm_detect_info->algorithm_cfg_size =
|
||
|
@@ -806,9 +822,7 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||
|
p_usm_detect_info,
|
||
|
detect_info_size);
|
||
|
if (rc || (detect_info.detect_timeout == USF_NO_WAIT_TIMEOUT)) {
|
||
|
- if (detect_info_size >
|
||
|
- sizeof(struct usm_session_cmd_detect_info))
|
||
|
- kfree(p_usm_detect_info);
|
||
|
+ kfree(p_allocated_memory);
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
@@ -828,25 +842,24 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||
|
USF_US_DETECT_UNDEF),
|
||
|
timeout);
|
||
|
/* In the case of timeout, "no US" is assumed */
|
||
|
- if (rc < 0) {
|
||
|
+ if (rc < 0)
|
||
|
pr_err("%s: Getting US detection failed rc[%d]\n",
|
||
|
__func__, rc);
|
||
|
- return rc;
|
||
|
- }
|
||
|
-
|
||
|
- usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type;
|
||
|
- detect_info.is_us = (usf_xx->us_detect_type == USF_US_DETECT_YES);
|
||
|
- rc = copy_to_user((void __user *)arg,
|
||
|
- &detect_info,
|
||
|
- sizeof(detect_info));
|
||
|
- if (rc) {
|
||
|
- pr_err("%s: copy detect_info to user; rc=%d\n",
|
||
|
- __func__, rc);
|
||
|
- rc = -EFAULT;
|
||
|
+ else {
|
||
|
+ usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type;
|
||
|
+ detect_info.is_us =
|
||
|
+ (usf_xx->us_detect_type == USF_US_DETECT_YES);
|
||
|
+ rc = copy_to_user((void __user *)arg,
|
||
|
+ &detect_info,
|
||
|
+ sizeof(detect_info));
|
||
|
+ if (rc) {
|
||
|
+ pr_err("%s: copy detect_info to user; rc=%d\n",
|
||
|
+ __func__, rc);
|
||
|
+ rc = -EFAULT;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
- if (detect_info_size > sizeof(struct usm_session_cmd_detect_info))
|
||
|
- kfree(p_usm_detect_info);
|
||
|
+ kfree(p_allocated_memory);
|
||
|
|
||
|
return rc;
|
||
|
} /* usf_set_us_detection */
|
||
|
@@ -947,16 +960,14 @@ static int usf_set_rx_info(struct usf_type *usf, unsigned long arg)
|
||
|
if (rc)
|
||
|
return rc;
|
||
|
|
||
|
- if (usf_xx->buffer_size && usf_xx->buffer_count) {
|
||
|
- rc = q6usm_us_client_buf_alloc(
|
||
|
- IN,
|
||
|
- usf_xx->usc,
|
||
|
- usf_xx->buffer_size,
|
||
|
- usf_xx->buffer_count);
|
||
|
- if (rc) {
|
||
|
- (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
|
||
|
- return rc;
|
||
|
- }
|
||
|
+ rc = q6usm_us_client_buf_alloc(
|
||
|
+ IN,
|
||
|
+ usf_xx->usc,
|
||
|
+ usf_xx->buffer_size,
|
||
|
+ usf_xx->buffer_count);
|
||
|
+ if (rc) {
|
||
|
+ (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
|
||
|
+ return rc;
|
||
|
}
|
||
|
|
||
|
rc = q6usm_dec_cfg_blk(usf_xx->usc,
|
||
|
@@ -1175,10 +1186,15 @@ static int usf_get_version(unsigned long arg)
|
||
|
return -EFAULT;
|
||
|
}
|
||
|
|
||
|
- /* version_info.buf is pointer to place for the version string */
|
||
|
+ if (version_info.buf_size < sizeof(DRV_VERSION)) {
|
||
|
+ pr_err("%s: buf_size (%d) < version string size (%d)\n",
|
||
|
+ __func__, version_info.buf_size, sizeof(DRV_VERSION));
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
rc = copy_to_user(version_info.pbuf,
|
||
|
DRV_VERSION,
|
||
|
- version_info.buf_size);
|
||
|
+ sizeof(DRV_VERSION));
|
||
|
if (rc) {
|
||
|
pr_err("%s: copy to version_info.pbuf; rc=%d\n",
|
||
|
__func__, rc);
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|