From: Christopher Lais Date: Sat, 1 May 2010 20:51:48 +0000 (-0500) Subject: binder: Fix memory corruption via page aliasing X-Git-Tag: firefly_0821_release~11607 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6bdee543a3281e7d53e2902fedae529ced5e0c7e;p=firefly-linux-kernel-4.4.55.git 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 --- diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index cd53c64f7395..17e5c24eae16 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -3026,11 +3026,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++; }