From 96d5d960fef4dee415e109cb1d0c8f3352985d05 Mon Sep 17 00:00:00 2001 From: Anthony Date: Sat, 3 Oct 2026 00:02:40 +0200 Subject: [PATCH] binder: fix NULL lock dereference in shrinker on Linux >= 6.13 Since Linux 6.13 the list_lru walk callback no longer receives the lru lock; it lives in struct list_lru_one. binder_alloc_free_page_no_lock() passes NULL as the lock, so binder_alloc_free_page() ends up calling spin_unlock(NULL) as soon as kswapd runs the binder shrinker: BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:_raw_spin_unlock+0x9/0x40 Call Trace: binder_alloc_free_page+0xe1/0x360 [binder_linux] __list_lru_walk_one+0xdf/0x230 list_lru_walk_node+0x52/0x230 binder_shrink_scan+0xa7/0x100 [binder_linux] do_shrink_slab+0x154/0x3a0 ... kswapd+0x1e2/0x360 The machine then hangs, typically under memory pressure, right after resuming from suspend, or while writing a hibernation image. Fall back to &lru->lock when no lock is passed, as upstream binder does. --- binder/binder_alloc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/binder/binder_alloc.c b/binder/binder_alloc.c index 45c2c56..9afc7bb 100644 --- a/binder/binder_alloc.c +++ b/binder/binder_alloc.c @@ -1003,6 +1003,10 @@ enum lru_status binder_alloc_free_page(struct list_head *item, size_t index; struct vm_area_struct *vma; + /* Since 6.13 the list_lru callback gets no lock; it lives in lru. */ + if (!lock) + lock = &lru->lock; + alloc = page->alloc; if (!mutex_trylock(&alloc->mutex)) goto err_get_alloc_mutex_failed;