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
}
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);
}