DivestOS/Patches/Linux_CVEs/CVE-2016-8481/4.4/0002.patch
2017-11-07 17:32:46 -05:00

186 lines
5.1 KiB
Diff

From c8c16b7406c68a5a9f35c5afbfcafd893e197425 Mon Sep 17 00:00:00 2001
From: Sudheer Papothi <spapothi@codeaurora.org>
Date: Wed, 26 Oct 2016 01:07:04 +0530
Subject: drivers: qcom: ultrasound: Lock async driver calls
Adds lock to ioctl and other external calls to driver.
Adds missing null check in __usf_set_stream_param.
Change-Id: I142f31c6bb46d6a394ad012077e1703875a120ad
Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
---
drivers/misc/qcom/qdsp6v2/ultrasound/usf.c | 66 ++++++++++++++++++++++++++----
1 file changed, 59 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c b/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c
index 7572374..3bb95f5 100644
--- a/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c
+++ b/drivers/misc/qcom/qdsp6v2/ultrasound/usf.c
@@ -23,6 +23,7 @@
#include <linux/time.h>
#include <linux/kmemleak.h>
#include <linux/wakelock.h>
+#include <linux/mutex.h>
#include <sound/apr_audio.h>
#include <linux/qdsp6v2/usf.h>
#include "q6usm.h"
@@ -135,6 +136,8 @@ struct usf_type {
uint16_t conflicting_event_filters;
/* The requested buttons bitmap */
uint16_t req_buttons_bitmap;
+ /* Mutex for exclusive operations (all public APIs) */
+ struct mutex mutex;
};
struct usf_input_dev_type {
@@ -1403,9 +1406,22 @@ static int __usf_set_stream_param(struct usf_xx_type *usf_xx,
int dir)
{
struct us_client *usc = usf_xx->usc;
- struct us_port_data *port = &usc->port[dir];
+ struct us_port_data *port;
int rc = 0;
+ if (usc == NULL) {
+ pr_err("%s: usc is null\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ port = &usc->port[dir];
+ if (port == NULL) {
+ pr_err("%s: port is null\n",
+ __func__);
+ return -EFAULT;
+ }
+
if (port->param_buf == NULL) {
pr_err("%s: parameter buffer is null\n",
__func__);
@@ -1538,10 +1554,12 @@ static int usf_get_stream_param(struct usf_xx_type *usf_xx,
return __usf_get_stream_param(usf_xx, &get_stream_param, dir);
} /* usf_get_stream_param */
-static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long __usf_ioctl(struct usf_type *usf,
+ unsigned int cmd,
+ unsigned long arg)
{
+
int rc = 0;
- struct usf_type *usf = file->private_data;
struct usf_xx_type *usf_xx = NULL;
switch (cmd) {
@@ -1704,6 +1722,18 @@ static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
release_xx(usf_xx);
return rc;
+} /* __usf_ioctl */
+
+static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct usf_type *usf = file->private_data;
+ int rc = 0;
+
+ mutex_lock(&usf->mutex);
+ rc = __usf_ioctl(usf, cmd, arg);
+ mutex_unlock(&usf->mutex);
+
+ return rc;
} /* usf_ioctl */
#ifdef CONFIG_COMPAT
@@ -2147,12 +2177,11 @@ static int usf_get_stream_param32(struct usf_xx_type *usf_xx,
return __usf_get_stream_param(usf_xx, &get_stream_param, dir);
} /* usf_get_stream_param32 */
-static long usf_compat_ioctl(struct file *file,
+static long __usf_compat_ioctl(struct usf_type *usf,
unsigned int cmd,
unsigned long arg)
{
int rc = 0;
- struct usf_type *usf = file->private_data;
struct usf_xx_type *usf_xx = NULL;
switch (cmd) {
@@ -2160,7 +2189,7 @@ static long usf_compat_ioctl(struct file *file,
case US_START_RX:
case US_STOP_TX:
case US_STOP_RX: {
- return usf_ioctl(file, cmd, arg);
+ return __usf_ioctl(usf, cmd, arg);
}
case US_SET_TX_INFO32: {
@@ -2269,6 +2298,20 @@ static long usf_compat_ioctl(struct file *file,
release_xx(usf_xx);
return rc;
+} /* __usf_compat_ioctl */
+
+static long usf_compat_ioctl(struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ struct usf_type *usf = file->private_data;
+ int rc = 0;
+
+ mutex_lock(&usf->mutex);
+ rc = __usf_compat_ioctl(usf, cmd, arg);
+ mutex_unlock(&usf->mutex);
+
+ return rc;
} /* usf_compat_ioctl */
#endif /* CONFIG_COMPAT */
@@ -2277,13 +2320,17 @@ static int usf_mmap(struct file *file, struct vm_area_struct *vms)
struct usf_type *usf = file->private_data;
int dir = OUT;
struct usf_xx_type *usf_xx = &usf->usf_tx;
+ int rc = 0;
+ mutex_lock(&usf->mutex);
if (vms->vm_flags & USF_VM_WRITE) { /* RX buf mapping */
dir = IN;
usf_xx = &usf->usf_rx;
}
+ rc = q6usm_get_virtual_address(dir, usf_xx->usc, vms);
+ mutex_unlock(&usf->mutex);
- return q6usm_get_virtual_address(dir, usf_xx->usc, vms);
+ return rc;
}
static uint16_t add_opened_dev(int minor)
@@ -2336,6 +2383,8 @@ static int usf_open(struct inode *inode, struct file *file)
usf->usf_tx.us_detect_type = USF_US_DETECT_UNDEF;
usf->usf_rx.us_detect_type = USF_US_DETECT_UNDEF;
+ mutex_init(&usf->mutex);
+
pr_debug("%s:usf in open\n", __func__);
return 0;
}
@@ -2346,6 +2395,7 @@ static int usf_release(struct inode *inode, struct file *file)
pr_debug("%s: release entry\n", __func__);
+ mutex_lock(&usf->mutex);
usf_release_input(usf);
usf_disable(&usf->usf_tx);
@@ -2354,6 +2404,8 @@ static int usf_release(struct inode *inode, struct file *file)
s_opened_devs[usf->dev_ind] = 0;
wakeup_source_trash(&usf_wakeup_source);
+ mutex_unlock(&usf->mutex);
+ mutex_destroy(&usf->mutex);
kfree(usf);
pr_debug("%s: release exit\n", __func__);
return 0;
--
cgit v1.1