summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-01-16 04:28:58 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-16 04:28:58 -0800
commit20dcab7b2dc7dac915008723988474afe120bb12 (patch)
tree75fe630657b5f17246e6f750a4c3869963d985a2 /drivers
parent63e23a6cfe95525745eb90a62aee7f3cbca78ab5 (diff)
parentc7adff7a0cedd39a64f3f06b1d8a4be59a6a0bd5 (diff)
Merge "ion: Fix use after free during ION_IOC_ALLOC"
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/android/ion/ion.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index e0af922a0329..81bda878a7ec 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -503,9 +503,9 @@ static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
return 0;
}
-struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+static struct ion_handle *__ion_alloc(struct ion_client *client, size_t len,
size_t align, unsigned int heap_id_mask,
- unsigned int flags)
+ unsigned int flags, bool grab_handle)
{
struct ion_handle *handle;
struct ion_device *dev = client->dev;
@@ -600,6 +600,8 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
return handle;
mutex_lock(&client->lock);
+ if (grab_handle)
+ ion_handle_get(handle);
ret = ion_handle_add(client, handle);
mutex_unlock(&client->lock);
if (ret) {
@@ -609,6 +611,13 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
return handle;
}
+
+struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+ size_t align, unsigned int heap_id_mask,
+ unsigned int flags)
+{
+ return __ion_alloc(client, len, align, heap_id_mask, flags, false);
+}
EXPORT_SYMBOL(ion_alloc);
static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle)
@@ -1493,10 +1502,10 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct ion_handle *handle;
- handle = ion_alloc(client, data.allocation.len,
+ handle = __ion_alloc(client, data.allocation.len,
data.allocation.align,
data.allocation.heap_id_mask,
- data.allocation.flags);
+ data.allocation.flags, true);
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -1573,11 +1582,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (dir & _IOC_READ) {
if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
- if (cleanup_handle)
+ if (cleanup_handle) {
ion_free(client, cleanup_handle);
+ ion_handle_put(cleanup_handle);
+ }
return -EFAULT;
}
}
+ if (cleanup_handle)
+ ion_handle_put(cleanup_handle);
return ret;
}