]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Add warning to detect memory leak in bpf_selem_unlink_nofail()
authorAmery Hung <ameryhung@gmail.com>
Wed, 18 Mar 2026 22:42:19 +0000 (15:42 -0700)
committerMartin KaFai Lau <martin.lau@kernel.org>
Thu, 19 Mar 2026 19:14:28 +0000 (12:14 -0700)
While very unlikely, local storage theoretically may leak memory of the
size of "struct bpf_local_storage" when destroy() fails to grab
local_storage->lock and initializes selem->local_storage before other
racing map_free() see it. Warn the user to allow debugging the issue
instead of leaking the memory silently.

Note that test_maps in bpf selftests already stress tested
bpf_selem_unlink_nofail() by creating 4096 sockets and then immediately
destroying them in multiple threads. With 64 threads, 64 x 4096 socket
local storages were created and destroyed during the test and no warning
in the function were triggered.

Signed-off-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://patch.msgid.link/20260318224219.615105-1-ameryhung@gmail.com
kernel/bpf/bpf_local_storage.c

index 4c6079d2cf28d0ebadfc188cd6e08f858e3d15ff..cad17ca8552f8d659606ef4833f8eee39d10198b 100644 (file)
@@ -497,6 +497,14 @@ static void bpf_selem_unlink_nofail(struct bpf_local_storage_elem *selem,
                        }
                        raw_res_spin_unlock_irqrestore(&local_storage->lock, flags);
                }
+               /*
+                * Highly unlikely scenario: memory leak
+                *
+                * When destroy() fails to acqurire local_storage->lock and initializes
+                * selem->local_storage to NULL before any racing map_free() sees the same
+                * selem, no one will free the local storage.
+                */
+               WARN_ON_ONCE(err && !in_map_free);
                if (!err || !in_map_free)
                        RCU_INIT_POINTER(selem->local_storage, NULL);
        }