mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
binder: Fix memory corruption via page aliasing
binder_deferred_release was not unmapping the page from the buffer before freeing it, causing memory corruption. This only happened when page(s) had not been freed by binder_update_page_range, which properly unmaps the pages. This only happens on architectures with VIPT aliasing. To reproduce, create a program which opens, mmaps, munmaps, then closes the binder very quickly. This should leave a page allocated when the binder is released. When binder_deferrred_release is called on the close, the page will remain mapped to the address in the linear proc->buffer. Later, we may map the same physical page to a different virtual address that has different coloring, and this may cause aliasing to occur. PAGE_POISONING will greatly increase your chances of noticing any problems. Change-Id: I6941bf212881b8bf846bdfda43d3609c7ae4892e Signed-off-by: Christopher Lais <chris+android@zenthought.org>
This commit is contained in:
committed by
Colin Cross
parent
f665be65af
commit
29023ce8df
@@ -3036,11 +3036,14 @@ static void binder_deferred_release(struct binder_proc *proc)
|
||||
int i;
|
||||
for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) {
|
||||
if (proc->pages[i]) {
|
||||
void *page_addr = proc->buffer + i * PAGE_SIZE;
|
||||
binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
|
||||
"binder_release: %d: "
|
||||
"page %d at %p not freed\n",
|
||||
proc->pid, i,
|
||||
proc->buffer + i * PAGE_SIZE);
|
||||
page_addr);
|
||||
unmap_kernel_range((unsigned long)page_addr,
|
||||
PAGE_SIZE);
|
||||
__free_page(proc->pages[i]);
|
||||
page_count++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user