diff options
author | Jitendra Kumar <jitendrak@nvidia.com> | 2016-10-27 14:05:00 +0530 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2017-06-20 11:14:33 -0700 |
commit | 707cd5f568f3521090d31dec663f54d7fca08347 (patch) | |
tree | d02ce0d3023a1b13e3912d0e2745891950148b9a | |
parent | ec9ac25833e9e5972b1dcbfc2f9140259dc71393 (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.c | 42 |
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; } |