summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJitendra Kumar <jitendrak@nvidia.com>2016-10-27 14:05:00 +0530
committerWinnie Hsu <whsu@nvidia.com>2017-06-20 11:14:33 -0700
commit707cd5f568f3521090d31dec663f54d7fca08347 (patch)
treed02ce0d3023a1b13e3912d0e2745891950148b9a
parentec9ac25833e9e5972b1dcbfc2f9140259dc71393 (diff)
media: tegra: nvavp: Fix UAF issue.
Use locking to protect generated fd, so that it can't be freed before channel open completes. Also add null value checks in release call. CVE-2016-8449 (A-31798848) Bug 1830023 Bug 1849492 Change-Id: Ie6e2b29c7132fdfdff6b0bfa75440bd43afffd5f Signed-off-by: Gagan Grover <ggrover@nvidia.com> Reviewed-on: http://git-master/r/1285817 (cherry picked from commit 2ff0fdedfd65f269359d6540df4662e958681aa7) Reviewed-on: http://git-master/r/1299505 (cherry picked from commit ea1af2ce5a746bda36205357c9e0adaf527026bb) Reviewed-on: http://git-master/r/1489467 (cherry picked from commit 89559abb25f82dc333eafa26391be0a50d6e9e0a) Reviewed-on: http://git-master/r/1504674 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Tested-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: Winnie Hsu <whsu@nvidia.com>
-rw-r--r--drivers/media/platform/tegra/nvavp/nvavp_dev.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/drivers/media/platform/tegra/nvavp/nvavp_dev.c b/drivers/media/platform/tegra/nvavp/nvavp_dev.c
index f2cb6a593dd2..25dee33ea9aa 100644
--- a/drivers/media/platform/tegra/nvavp/nvavp_dev.c
+++ b/drivers/media/platform/tegra/nvavp/nvavp_dev.c
@@ -1,7 +1,7 @@
/*
* drivers/media/video/tegra/nvavp/nvavp_dev.c
*
- * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
@@ -2037,10 +2037,17 @@ out:
static int tegra_nvavp_video_release(struct inode *inode, struct file *filp)
{
- struct nvavp_clientctx *clientctx = filp->private_data;
- struct nvavp_info *nvavp = clientctx->nvavp;
+ struct nvavp_clientctx *clientctx;
+ struct nvavp_info *nvavp;
int ret = 0;
+ clientctx = filp->private_data;
+ if (!clientctx)
+ return ret;
+ nvavp = clientctx->nvavp;
+ if (!nvavp)
+ return ret;
+
mutex_lock(&nvavp->open_lock);
filp->private_data = NULL;
ret = tegra_nvavp_release(clientctx, NVAVP_VIDEO_CHANNEL);
@@ -2053,10 +2060,17 @@ static int tegra_nvavp_video_release(struct inode *inode, struct file *filp)
static int tegra_nvavp_audio_release(struct inode *inode,
struct file *filp)
{
- struct nvavp_clientctx *clientctx = filp->private_data;
- struct nvavp_info *nvavp = clientctx->nvavp;
+ struct nvavp_clientctx *clientctx;
+ struct nvavp_info *nvavp;
int ret = 0;
+ clientctx = filp->private_data;
+ if (!clientctx)
+ return ret;
+ nvavp = clientctx->nvavp;
+ if (!nvavp)
+ return ret;
+
mutex_lock(&nvavp->open_lock);
filp->private_data = NULL;
ret = tegra_nvavp_release(clientctx, NVAVP_AUDIO_CHANNEL);
@@ -2068,9 +2082,15 @@ static int tegra_nvavp_audio_release(struct inode *inode,
int tegra_nvavp_audio_client_release(nvavp_clientctx_t client)
{
struct nvavp_clientctx *clientctx = client;
- struct nvavp_info *nvavp = clientctx->nvavp;
+ struct nvavp_info *nvavp;
int ret = 0;
+ if (!clientctx)
+ return ret;
+ nvavp = clientctx->nvavp;
+ if (!nvavp)
+ return ret;
+
mutex_lock(&nvavp->open_lock);
ret = tegra_nvavp_release(clientctx, NVAVP_AUDIO_CHANNEL);
mutex_unlock(&nvavp->open_lock);
@@ -2112,10 +2132,8 @@ nvavp_channel_open(struct file *filp, struct nvavp_channel_open_args *arg)
return err;
}
- fd_install(fd, file);
-
- nonseekable_open(file->f_inode, filp);
mutex_lock(&nvavp->open_lock);
+
err = tegra_nvavp_open(nvavp,
(struct nvavp_clientctx **)&file->private_data,
clientctx->channel_id);
@@ -2125,9 +2143,13 @@ nvavp_channel_open(struct file *filp, struct nvavp_channel_open_args *arg)
mutex_unlock(&nvavp->open_lock);
return err;
}
- mutex_unlock(&nvavp->open_lock);
arg->channel_fd = fd;
+
+ nonseekable_open(file->f_inode, filp);
+ fd_install(fd, file);
+
+ mutex_unlock(&nvavp->open_lock);
return err;
}