fix: race condition in jp_spec_setup causing use-after-free

mutex_init(&spec->lock) was called in jp_spec_setup while another
thread could be holding the lock in jp_spec_applymods. Re-initializing
a locked mutex corrupts its state, allowing both threads to enter
the critical section simultaneously.

This caused use-after-free when:
1. send.c holds spec->lock, uses spec->pkt
2. jp_spec_setup re-inits the locked mutex (broken state)
3. jp_spec_setup acquires the "lock" immediately
4. jp_spec_setup does kfree(spec->pkt)
5. send.c continues using freed memory -> crash

Fix: move mutex_init to wg_newlink where it's called once during
device creation, before any concurrent access.
This commit is contained in:
Arsolitt
2026-03-25 19:22:15 +03:00
committed by pokamest
parent 7239c05579
commit ac946a9df1
2 changed files with 3 additions and 5 deletions

View File

@@ -362,12 +362,14 @@ static int wg_newlink(struct net_device *dev,
{
struct net *link_net = rtnl_newlink_link_net(params);
struct wg_device *wg = netdev_priv(dev);
int ret = -ENOMEM;
int ret = -ENOMEM, i;
rcu_assign_pointer(wg->creating_net, link_net);
init_rwsem(&wg->static_identity.lock);
mutex_init(&wg->socket_update_lock);
mutex_init(&wg->device_update_lock);
for (i = 0; i < ARRAY_SIZE(wg->ispecs); ++i)
mutex_init(&wg->ispecs[i].lock);
wg_allowedips_init(&wg->peer_allowedips);
wg_cookie_checker_init(&wg->cookie_checker, wg);
INIT_LIST_HEAD(&wg->peer_list);

View File

@@ -255,8 +255,6 @@ int jp_spec_setup(struct jp_spec *spec) {
char* buf;
LIST_HEAD(head);
mutex_init(&spec->lock);
mutex_lock(&spec->lock);
kfree(spec->pkt);
@@ -303,8 +301,6 @@ int jp_spec_setup(struct jp_spec *spec) {
goto error;
}
spec->pkt_size = 0;
spec->mods_size = 0;
list_for_each_entry_reverse(tag, &head, head) {
if (tag->pkt) {
memcpy(spec->pkt + spec->pkt_size, tag->pkt, tag->pkt_size);