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.
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, but that area may be returned by alloc_page with the
mapping to a different physical page in-tact.
PAGE_POISONING will greatly increase your chances of noticing any
problems. Adding debug to show the addresses of the allog_page'd pages
(page_address(page->pages[i])) and the proc->buffer on allocation in
binder_mmap and on free in binder_deferred_release may help with
verifying.
Change-Id: I6941bf212881b8bf846bdfda43d3609c7ae4892e
---
drivers/staging/android/binder.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index cd53c64..1d06967 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -3026,11 +3026,13 @@ 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++;
}
--
1.7.1
--
unsubscribe: [email protected]
website: http://groups.google.com/group/android-kernel