Skip to content

Commit 547b3aa

Browse files
jrfastabAlexei Starovoitov
authored andcommitted
bpf: sockmap, error path can not release psock in multi-map case
The current code, in the error path of sock_hash_ctx_update_elem, checks if the sock has a psock in the user data and if so decrements the reference count of the psock. However, if the error happens early in the error path we may have never incremented the psock reference count and if the psock exists because the sock is in another map then we may inadvertently decrement the reference count. Fix this by making the error path only call smap_release_sock if the error happens after the increment. Reported-by: [email protected] Fixes: 8111038 ("bpf: sockmap, add hash map support") Signed-off-by: John Fastabend <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent c48424d commit 547b3aa

File tree

1 file changed

+6
-11
lines changed

1 file changed

+6
-11
lines changed

kernel/bpf/sockmap.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,7 @@ static int __sock_map_ctx_update_elem(struct bpf_map *map,
18961896
e = kzalloc(sizeof(*e), GFP_ATOMIC | __GFP_NOWARN);
18971897
if (!e) {
18981898
err = -ENOMEM;
1899-
goto out_progs;
1899+
goto out_free;
19001900
}
19011901
}
19021902

@@ -2342,7 +2342,10 @@ static int sock_hash_ctx_update_elem(struct bpf_sock_ops_kern *skops,
23422342
if (err)
23432343
goto err;
23442344

2345-
/* bpf_map_update_elem() can be called in_irq() */
2345+
/* psock is valid here because otherwise above *ctx_update_elem would
2346+
* have thrown an error. It is safe to skip error check.
2347+
*/
2348+
psock = smap_psock_sk(sock);
23462349
raw_spin_lock_bh(&b->lock);
23472350
l_old = lookup_elem_raw(head, hash, key, key_size);
23482351
if (l_old && map_flags == BPF_NOEXIST) {
@@ -2360,12 +2363,6 @@ static int sock_hash_ctx_update_elem(struct bpf_sock_ops_kern *skops,
23602363
goto bucket_err;
23612364
}
23622365

2363-
psock = smap_psock_sk(sock);
2364-
if (unlikely(!psock)) {
2365-
err = -EINVAL;
2366-
goto bucket_err;
2367-
}
2368-
23692366
rcu_assign_pointer(e->hash_link, l_new);
23702367
rcu_assign_pointer(e->htab,
23712368
container_of(map, struct bpf_htab, map));
@@ -2388,12 +2385,10 @@ static int sock_hash_ctx_update_elem(struct bpf_sock_ops_kern *skops,
23882385
raw_spin_unlock_bh(&b->lock);
23892386
return 0;
23902387
bucket_err:
2388+
smap_release_sock(psock, sock);
23912389
raw_spin_unlock_bh(&b->lock);
23922390
err:
23932391
kfree(e);
2394-
psock = smap_psock_sk(sock);
2395-
if (psock)
2396-
smap_release_sock(psock, sock);
23972392
return err;
23982393
}
23992394

0 commit comments

Comments
 (0)