Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b4b89f9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ion: Fix use after free during ION_IOC_ALLOC"

parents ce960474 f430f884
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -507,9 +507,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;
@@ -604,6 +604,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) {
@@ -613,6 +615,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)
@@ -1488,10 +1497,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);

@@ -1568,11 +1577,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;
}