| From 58526090ece3582516e62779739a7d665a74708c Mon Sep 17 00:00:00 2001 |
| From: Christopher Lais <chris+android@zenthought.org> |
| Date: Sat, 1 May 2010 15:51:48 -0500 |
| Subject: staging: binder: Fix memory corruption via page aliasing |
| Patch-mainline: HEAD |
| Git-commit: 58526090ece3582516e62779739a7d665a74708c |
| |
| 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. |
| |
| Signed-off-by: Christopher Lais <chris+android@zenthought.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c |
| index 6d6fe7b..7491801 100644 |
| --- a/drivers/staging/android/binder.c |
| +++ b/drivers/staging/android/binder.c |
| @@ -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++; |
| } |