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

Commit 6f98a797 authored by Rakesh Naidu Bhaviripudi's avatar Rakesh Naidu Bhaviripudi Committed by Hemasri Yallanki
Browse files

msm: kgsl: Fix buffer overflow while capturing memory entries



We calculate the number of memory entries of a process first
to make sure we have enough memory. When saving the entries,
we use the ID of the entry as an array index. This can result
into array out of bound access as ID can be greater than
the number of memory entries calculated earlier.
Fix this by using the right array index.

Change-Id: I915e565330c21a2604354a05592ae15d62991617
Signed-off-by: default avatarRakesh Naidu Bhaviripudi <quic_rakeshb@quicinc.com>
Signed-off-by: default avatarHemasri Yallanki <quic_hyallank@quicinc.com>
parent 9dfd0a51
Loading
Loading
Loading
Loading
+10 −17
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-License-Identifier: GPL-2.0-only
/*
/*
 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
 */
 */


#include <linux/msm-bus.h>
#include <linux/msm-bus.h>
@@ -502,28 +503,15 @@ struct mem_entry {
	unsigned int type;
	unsigned int type;
} __packed;
} __packed;


static int _save_mem_entries(int id, void *ptr, void *data)
{
	struct kgsl_mem_entry *entry = ptr;
	struct mem_entry *m = (struct mem_entry *) data;
	unsigned int index = id - 1;

	m[index].gpuaddr = entry->memdesc.gpuaddr;
	m[index].size = entry->memdesc.size;
	m[index].type = kgsl_memdesc_get_memtype(&entry->memdesc);

	return 0;
}

static size_t snapshot_capture_mem_list(struct kgsl_device *device,
static size_t snapshot_capture_mem_list(struct kgsl_device *device,
		u8 *buf, size_t remain, void *priv)
		u8 *buf, size_t remain, void *priv)
{
{
	struct kgsl_snapshot_mem_list_v2 *header =
	struct kgsl_snapshot_mem_list_v2 *header =
		(struct kgsl_snapshot_mem_list_v2 *)buf;
		(struct kgsl_snapshot_mem_list_v2 *)buf;
	int num_mem = 0;
	int id, index = 0, ret = 0, num_mem = 0;
	int ret = 0;
	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
	struct kgsl_process_private *process = priv;
	struct kgsl_process_private *process = priv;
	struct mem_entry *m = (struct mem_entry *)(buf + sizeof(*header));
	struct kgsl_mem_entry *entry;


	/* we need a process to search! */
	/* we need a process to search! */
	if (process == NULL)
	if (process == NULL)
@@ -550,7 +538,12 @@ static size_t snapshot_capture_mem_list(struct kgsl_device *device,
	 * Walk through the memory list and store the
	 * Walk through the memory list and store the
	 * tuples(gpuaddr, size, memtype) in snapshot
	 * tuples(gpuaddr, size, memtype) in snapshot
	 */
	 */
	idr_for_each(&process->mem_idr, _save_mem_entries, data);
	idr_for_each_entry(&process->mem_idr, entry, id) {
		m[index].gpuaddr = entry->memdesc.gpuaddr;
		m[index].size = entry->memdesc.size;
		m[index].type = kgsl_memdesc_get_memtype(&entry->memdesc);
		index++;
	}


	ret = sizeof(*header) + (num_mem * sizeof(struct mem_entry));
	ret = sizeof(*header) + (num_mem * sizeof(struct mem_entry));
out:
out: