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

Commit 25b4ae55 authored by Raghu Ananya Arabolu's avatar Raghu Ananya Arabolu Committed by Pankaj Gupta
Browse files

msm: kgsl: Do not double free pages in kgsl_memdesc



We have a situation where the page count value is non-zero but the
pages pointer is pointing to memory that is already freed. We then
go on to access this invalid pages pointer to free the pages that
have already been freed. We now check for the validity of the pages
pointer before attempting to free it. Also set the page count to 0
before freeing pages and set the pages pointer to NULL after freeing
pages.

Change-Id: I2b8e63a5f2ad2245f0068214b8925b147435d5db
Signed-off-by: default avatarRaghu Ananya Arabolu <rarabolu@codeaurora.org>
Signed-off-by: default avatarPankaj Gupta <gpankaj@codeaurora.org>
parent e60bc8ba
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -265,12 +265,20 @@ void kgsl_pool_free_pages(struct page **pages, unsigned int pcount)
	if (pages == NULL || pcount == 0)
		return;

	if (WARN(!kern_addr_valid((unsigned long)pages),
		"Address of pages=%pK is not valid\n", pages))
		return;

	for (i = 0; i < pcount;) {
		/*
		 * Free each page or compound page group individually.
		 */
		struct page *p = pages[i];

		if (WARN(!kern_addr_valid((unsigned long)p),
			"Address of page=%pK is not valid\n", p))
			return;

		i += 1 << compound_order(p);
		kgsl_pool_free_page(p);
	}
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1053,8 +1053,11 @@ void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc)
		kfree(memdesc->sgt);
	}

	memdesc->page_count = 0;
	if (memdesc->pages)
		kgsl_free(memdesc->pages);
	memdesc->pages = NULL;

}
EXPORT_SYMBOL(kgsl_sharedmem_free);