aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Howlett <[email protected]>2022-06-27 15:18:59 +0000
committerakpm <[email protected]>2022-07-29 18:07:13 -0700
commitb0cab80ecd54ae3b2356bb081af0bffd538c8265 (patch)
tree9e380f660931ff9fe2b9e6aa77e88bb3a5ff4892
parenta43cfc87caaf46710c8027a8c23b8a55f1078f19 (diff)
android: binder: fix lockdep check on clearing vma
When munmapping a vma, the mmap_lock can be degraded to a write before calling close() on the file handle. The binder close() function calls binder_alloc_set_vma() to clear the vma address, which now has a lock dep check for writing on the mmap_lock. Change the lockdep check to ensure the reading lock is held while clearing and keep the write check while writing. Link: https://lkml.kernel.org/r/[email protected] Fixes: 472a68df605b ("android: binder: stop saving a pointer to the VMA") Signed-off-by: Liam R. Howlett <[email protected]> Reported-by: [email protected] Acked-by: Todd Kjos <[email protected]> Cc: "Arve Hjønnevåg" <[email protected]> Cc: Christian Brauner (Microsoft) <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Hridya Valsaraju <[email protected]> Cc: Joel Fernandes <[email protected]> Cc: Martijn Coenen <[email protected]> Cc: Suren Baghdasaryan <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
-rw-r--r--drivers/android/binder_alloc.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index f555eebceef6..1014beb12802 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -315,12 +315,19 @@ static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
{
unsigned long vm_start = 0;
+ /*
+ * Allow clearing the vma with holding just the read lock to allow
+ * munmapping downgrade of the write lock before freeing and closing the
+ * file using binder_alloc_vma_close().
+ */
if (vma) {
vm_start = vma->vm_start;
alloc->vma_vm_mm = vma->vm_mm;
+ mmap_assert_write_locked(alloc->vma_vm_mm);
+ } else {
+ mmap_assert_locked(alloc->vma_vm_mm);
}
- mmap_assert_write_locked(alloc->vma_vm_mm);
alloc->vma_addr = vm_start;
}