DivestOS/Patches/Linux_CVEs/CVE-2017-0518/1.patch

139 lines
3.8 KiB
Diff

From a064a44e03158dbf655a866ba21f5d1baa2dee9e Mon Sep 17 00:00:00 2001
From: Dennis Cagle <d-cagle@codeaurora.org>
Date: Fri, 6 Jan 2017 15:28:20 -0800
Subject: [PATCH] QBT1000: copy qseecom handle to user when loading/unloading
app
QBT1000 provides IOCTLs for loading and unloading a QSEE app.
In the input structure for these IOCTLs there is a pointer
to a qseecom handle which serves as an output parameter for
the IOCTLs. That is, the given handle (in client address space)
should be set to a valid handle value on load, and should be set
to 0 on unload.
The driver was missing a proper copy_to_user() call for this handle,
which sometimes resulted in unload not setting the handle to 0.
Bug: 32372915
Bug: 32370896
CRs-fixed: 1059327
Change-Id: I31f205afb1f9bf0b6243e3f20f54022525c93b28
Signed-off-by: Lior Barenboim <liorb@codeaurora.org>
Signed-off-by: Dennis Cagle <d-cagle@codeaurora.org>
---
drivers/soc/qcom/qbt1000.c | 59 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 55 insertions(+), 4 deletions(-)
diff --git a/drivers/soc/qcom/qbt1000.c b/drivers/soc/qcom/qbt1000.c
index 101fcedd1f2c0..961800e2f963f 100755
--- a/drivers/soc/qcom/qbt1000.c
+++ b/drivers/soc/qcom/qbt1000.c
@@ -772,6 +772,7 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
case QBT1000_LOAD_APP:
{
struct qbt1000_app app;
+ struct qseecom_handle *app_handle;
if (copy_from_user(&app, priv_arg,
sizeof(app)) != 0) {
@@ -782,8 +783,15 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
goto end;
}
+ if (!app.app_handle) {
+ dev_err(drvdata->dev, "%s: LOAD app_handle is null\n",
+ __func__);
+ rc = -EINVAL;
+ goto end;
+ }
+
/* start the TZ app */
- rc = qseecom_start_app(app.app_handle, app.name, app.size);
+ rc = qseecom_start_app(&app_handle, app.name, app.size);
if (rc == 0) {
g_app_buf_size = app.size;
} else {
@@ -792,36 +800,79 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
goto end;
}
+ /* copy the app handle to user */
+ rc = copy_to_user((void __user *)app.app_handle, &app_handle,
+ sizeof(*app.app_handle));
+
+ if (rc != 0) {
+ dev_err(drvdata->dev,
+ "%s: Failed copy 2us LOAD rc:%d\n",
+ __func__, rc);
+ rc = -ENOMEM;
+ goto end;
+ }
+
break;
}
case QBT1000_UNLOAD_APP:
{
struct qbt1000_app app;
+ struct qseecom_handle *app_handle;
if (copy_from_user(&app, priv_arg,
sizeof(app)) != 0) {
rc = -ENOMEM;
dev_err(drvdata->dev,
- "%s: Failed copy from user space-LOAD\n",
+ "%s: Failed copy from user space-UNLOAD\n",
__func__);
goto end;
}
- /* if the app hasn't been loaded already, return err */
if (!app.app_handle) {
+ dev_err(drvdata->dev, "%s: UNLOAD app_handle is null\n",
+ __func__);
+ rc = -EINVAL;
+ goto end;
+ }
+
+ rc = copy_from_user(&app_handle, app.app_handle,
+ sizeof(app_handle));
+
+ if (rc != 0) {
+ dev_err(drvdata->dev,
+ "%s: Failed copy from user space-UNLOAD handle rc:%d\n",
+ __func__, rc);
+ rc = -ENOMEM;
+ goto end;
+ }
+
+ /* if the app hasn't been loaded already, return err */
+ if (!app_handle) {
dev_err(drvdata->dev, "%s: App not loaded\n",
__func__);
rc = -EINVAL;
goto end;
}
- rc = qseecom_shutdown_app(app.app_handle);
+ rc = qseecom_shutdown_app(&app_handle);
if (rc != 0) {
dev_err(drvdata->dev, "%s: App failed to shutdown\n",
__func__);
goto end;
}
+ /* copy the app handle (should be null) to user */
+ rc = copy_to_user((void __user *)app.app_handle, &app_handle,
+ sizeof(*app.app_handle));
+
+ if (rc != 0) {
+ dev_err(drvdata->dev,
+ "%s: Failed copy 2us UNLOAD rc:%d\n",
+ __func__, rc);
+ rc = -ENOMEM;
+ goto end;
+ }
+
break;
}
case QBT1000_SEND_TZCMD: