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

Commit b1312afc authored by Prasad Sodagudi's avatar Prasad Sodagudi Committed by Matt Wagantall
Browse files

ion: validate ion client in ion_debug_client_show() and extract data



ion client can get created and destroyed dynamically.
Client data struct may not be in proper state if one core is reading
client information and other core is destroying the same client.
There is no synchronization between ion_debug_client_show() and
ion_client_destroy(), that leaves client data structures in
uncertain state and which may lead to system crash.

So add a check in ion_debug_client_show(), to verify whether the client
is part of ion device rb tree or not before retrieving client data.

CRs-Fixed: 743714
Change-Id: Ic4c2f9dff905d9bb8fbf2e56b7c6396dc01bdf8f
Signed-off-by: default avatarPrasad Sodagudi <psodagud@codeaurora.org>
parent ddcb18f0
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -119,6 +119,8 @@ struct ion_handle {
	int id;
};

static struct ion_device *ion_dev;

bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
{
	return (buffer->flags & ION_FLAG_CACHED) &&
@@ -738,7 +740,30 @@ EXPORT_SYMBOL(ion_unmap_kernel);
static int ion_debug_client_show(struct seq_file *s, void *unused)
{
	struct ion_client *client = s->private;
	struct rb_node *n;
	struct rb_node *n, *cnode;
	bool found = false;

	down_write(&ion_dev->lock);

	if (!client || (client->dev != ion_dev)) {
		up_write(&ion_dev->lock);
		return -EINVAL;
	}

	cnode = rb_first(&ion_dev->clients);
	for ( ; cnode; cnode = rb_next(cnode)) {
		struct ion_client *c = rb_entry(cnode,
				struct ion_client, node);
		if (client == c) {
			found = true;
			break;
		}
	}

	if (!found) {
		up_write(&ion_dev->lock);
		return -EINVAL;
	}

	seq_printf(s, "%16.16s: %16.16s : %16.16s : %12.12s\n",
			"heap_name", "size_in_bytes", "handle refcount",
@@ -758,6 +783,7 @@ static int ion_debug_client_show(struct seq_file *s, void *unused)
		seq_printf(s, "\n");
	}
	mutex_unlock(&client->lock);
	up_write(&ion_dev->lock);
	return 0;
}

@@ -1930,6 +1956,7 @@ debugfs_done:
	init_rwsem(&idev->lock);
	plist_head_init(&idev->heaps);
	idev->clients = RB_ROOT;
	ion_dev = idev;
	return idev;
}