summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/nvmap
diff options
context:
space:
mode:
authorTuomas Tynkkynen <ttynkkynen@nvidia.com>2012-07-31 15:01:04 +0300
committerSimone Willett <swillett@nvidia.com>2012-08-10 23:15:03 -0700
commit70d4ced2d12a1251202d67ffae7f5c0b3013cc94 (patch)
tree34a76e46b9be21b6f785073600d9a5df0d427e2e /drivers/video/tegra/nvmap
parent642d37a0eee196d0ce811dd11bb7af5ba281ee3a (diff)
video: tegra: nvmap: fix usermode input validation
nvmap_pin_ids accepts a list of handles to pin, which are passed directly from usermode when called from nvmap_ioctl_pinop. However, if invalid handles are passed in, the function might still access them as valid handles, and cause a crash. Bug 1023954 Change-Id: I6b98a2ef448bb496be7d569ddd4fb516fc399cba Signed-off-by: Tuomas Tynkkynen <ttynkkynen@nvidia.com> Reviewed-on: http://git-master/r/119667 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/nvmap')
-rw-r--r--drivers/video/tegra/nvmap/nvmap.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/video/tegra/nvmap/nvmap.c b/drivers/video/tegra/nvmap/nvmap.c
index b7fd695d04ee..a0dcf26337f8 100644
--- a/drivers/video/tegra/nvmap/nvmap.c
+++ b/drivers/video/tegra/nvmap/nvmap.c
@@ -3,7 +3,7 @@
*
* Memory manager for Tegra GPU
*
- * Copyright (c) 2009-2011, NVIDIA Corporation.
+ * Copyright (c) 2009-2012, NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -271,7 +271,7 @@ int nvmap_pin_ids(struct nvmap_client *client,
* if the caller crashes after pinning a global handle, the handle
* will be permanently leaked. */
nvmap_ref_lock(client);
- for (i = 0; i < nr && !ret; i++) {
+ for (i = 0; i < nr; i++) {
ref = _nvmap_validate_id_locked(client, ids[i]);
if (ref) {
atomic_inc(&ref->pin);
@@ -280,19 +280,19 @@ int nvmap_pin_ids(struct nvmap_client *client,
struct nvmap_handle *verify;
nvmap_ref_unlock(client);
verify = nvmap_validate_get(client, ids[i]);
- if (verify)
+ if (verify) {
nvmap_warn(client, "%s pinning unreferenced "
"handle %p\n",
current->group_leader->comm, h[i]);
- else
+ } else {
+ h[i] = NULL;
ret = -EPERM;
+ }
nvmap_ref_lock(client);
}
}
nvmap_ref_unlock(client);
- nr = i;
-
if (ret)
goto out;
@@ -317,6 +317,9 @@ out:
if (ret) {
nvmap_ref_lock(client);
for (i = 0; i < nr; i++) {
+ if(!ids[i])
+ continue;
+
ref = _nvmap_validate_id_locked(client, ids[i]);
if (!ref) {
nvmap_warn(client, "%s freed handle %p "
@@ -330,7 +333,8 @@ out:
nvmap_ref_unlock(client);
for (i = 0; i < nr; i++)
- nvmap_handle_put(h[i]);
+ if(h[i])
+ nvmap_handle_put(h[i]);
}
return ret;