blob: dc17772c2bdccd418d9fa87545330d90f28ec8fc [file] [log] [blame]
From 58526090ece3582516e62779739a7d665a74708c Mon Sep 17 00:00:00 2001
From: Christopher Lais <>
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
Signed-off-by: Christopher Lais <>
Signed-off-by: Greg Kroah-Hartman <>
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_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,