mirror of https://gitee.com/openkylin/linux.git
staging: 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. Signed-off-by: Christopher Lais <chris+android@zenthought.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
4755b72e26
commit
58526090ec
|
@ -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++;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue