DivestOS/Patches/Linux_CVEs/CVE-2017-0519/0.patch

124 lines
4.1 KiB
Diff

From 2f264730e26a73da973c6eef0e1ee252294ec740 Mon Sep 17 00:00:00 2001
From: Dennis Cagle <d-cagle@codeaurora.org>
Date: Fri, 6 Jan 2017 15:28:29 -0800
Subject: [PATCH] soc: qcom: fingerprint: keep QSEE handle in kernel space
Move the QSEE handle from user space to kernel space.
In addition, fix possible overflow when checking that
the command and response buffers fit in the shared buffer.
Bug: 32372915
CRs-fixed: 1086530
Change-Id: I21b1866546a2825fe348a260c60e341bbe9600ea
Signed-off-by: Lior Barenboim <liorb@codeaurora.org>
Signed-off-by: Dennis Cagle <d-cagle@codeaurora.org>
---
drivers/soc/qcom/qbt1000.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/soc/qcom/qbt1000.c b/drivers/soc/qcom/qbt1000.c
index 961800e2f963f..f76cf0f45ecaa 100755
--- a/drivers/soc/qcom/qbt1000.c
+++ b/drivers/soc/qcom/qbt1000.c
@@ -86,6 +86,7 @@ struct qbt1000_drvdata {
uint32_t ssc_spi_port;
uint32_t ssc_spi_port_slave_index;
struct wakeup_source w_lock;
+ struct qseecom_handle *app_handle;
};
#define W_LOCK_DELAY_MS (2000)
@@ -110,7 +111,7 @@ static int get_cmd_rsp_buffers(struct qseecom_handle *hdl,
*cmd_len = ALIGN(*cmd_len, 64);
*rsp_len = ALIGN(*rsp_len, 64);
- if ((*rsp_len + *cmd_len) > g_app_buf_size)
+ if (((uint64_t)*rsp_len + (uint64_t)*cmd_len) > (uint64_t)g_app_buf_size)
return -ENOMEM;
*cmd = hdl->sbuf;
@@ -790,8 +791,19 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
goto end;
}
+ if (drvdata->app_handle) {
+ dev_err(drvdata->dev, "%s: LOAD app already loaded, unloading first\n",
+ __func__);
+ rc = qseecom_shutdown_app(&drvdata->app_handle);
+ if (rc != 0) {
+ dev_err(drvdata->dev, "%s: LOAD current app failed to shutdown\n",
+ __func__);
+ goto end;
+ }
+ }
+
/* start the TZ app */
- rc = qseecom_start_app(&app_handle, app.name, app.size);
+ rc = qseecom_start_app(&drvdata->app_handle, app.name, app.size);
if (rc == 0) {
g_app_buf_size = app.size;
} else {
@@ -800,7 +812,8 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
goto end;
}
- /* copy the app handle to user */
+ /* copy a fake app handle to user */
+ app_handle = drvdata->app_handle ? (struct qseecom_handle *)123456 : 0;
rc = copy_to_user((void __user *)app.app_handle, &app_handle,
sizeof(*app.app_handle));
@@ -817,7 +830,7 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
case QBT1000_UNLOAD_APP:
{
struct qbt1000_app app;
- struct qseecom_handle *app_handle;
+ struct qseecom_handle *app_handle = 0;
if (copy_from_user(&app, priv_arg,
sizeof(app)) != 0) {
@@ -847,14 +860,14 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
}
/* if the app hasn't been loaded already, return err */
- if (!app_handle) {
+ if (!drvdata->app_handle) {
dev_err(drvdata->dev, "%s: App not loaded\n",
__func__);
rc = -EINVAL;
goto end;
}
- rc = qseecom_shutdown_app(&app_handle);
+ rc = qseecom_shutdown_app(&drvdata->app_handle);
if (rc != 0) {
dev_err(drvdata->dev, "%s: App failed to shutdown\n",
__func__);
@@ -895,7 +908,7 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
}
/* if the app hasn't been loaded already, return err */
- if (!tzcmd.app_handle) {
+ if (!drvdata->app_handle) {
dev_err(drvdata->dev, "%s: App not loaded\n",
__func__);
rc = -EINVAL;
@@ -905,7 +918,7 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
/* init command and response buffers and align lengths */
aligned_cmd_len = tzcmd.req_buf_len;
aligned_rsp_len = tzcmd.rsp_buf_len;
- rc = get_cmd_rsp_buffers(tzcmd.app_handle,
+ rc = get_cmd_rsp_buffers(drvdata->app_handle,
(void **)&aligned_cmd,
&aligned_cmd_len,
(void **)&aligned_rsp,
@@ -930,7 +943,7 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
}
/* send cmd to TZ */
- rc = qseecom_send_command(tzcmd.app_handle,
+ rc = qseecom_send_command(drvdata->app_handle,
aligned_cmd,
aligned_cmd_len,
aligned_rsp,