BPF List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Michal Luczaj" <mhal@rbox.co>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH RFC v2 4/4] bpf: Mark bpf_iter__sockmap::sk as PTR_TRUSTED
Date: Mon, 02 Nov 2026 01:33:53 +0000	[thread overview]
Message-ID: <sashiko-outbox-192806@kernel.org> (raw)
In-Reply-To: <20261102-sockmap-update-limit-iter-v2-4-e96a63c43b39@rbox.co>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] bpf: unlocked socket destroy via bpf_sock_destroy() in iter/sockmap
--

commit 97a776f78529c30ceec62254569454f51205e10f
Author: Michal Luczaj <mhal@rbox.co>

bpf: Mark bpf_iter__sockmap::sk as PTR_TRUSTED

This commit marks the sk field in struct bpf_iter__sockmap as PTR_TRUSTED so
BPF helpers and kfuncs can accept the socket pointer provided by iter/sockmap
programs.

Link: https://msgid.link/DM92JCFA4X4U.30MTDH0KCPTJ@gmail.com

> diff --git a/net/core/sock_map.c b/net/core/sock_map.c
> index 057e2f3c0265e..2a2a073728189 100644
> --- a/net/core/sock_map.c
> +++ b/net/core/sock_map.c
> @@ -1989,7 +1989,7 @@ static struct bpf_iter_reg sock_map_iter_reg = {
>  		{ offsetof(struct bpf_iter__sockmap, key),
>  		  PTR_TO_BUF | PTR_MAYBE_NULL | MEM_RDONLY },
>  		{ offsetof(struct bpf_iter__sockmap, sk),
> -		  PTR_TO_BTF_ID_OR_NULL },
> +		  PTR_TO_BTF_ID_OR_NULL | PTR_TRUSTED },

[Severity: Critical]
Does marking bpf_iter__sockmap::sk with PTR_TRUSTED allow iter/sockmap
programs to call bpf_sock_destroy() on an unlocked socket?

In net/core/filter.c, tracing_iter_filter() permits bpf_sock_destroy() for
any BPF_TRACE_ITER program as long as the caller supplies a trusted
struct sock_common pointer:

net/core/filter.c:tracing_iter_filter() {
	if (btf_id_set8_contains(&bpf_sk_iter_kfunc_ids, kfunc_id) &&
	    prog->expected_attach_type != BPF_TRACE_ITER)
		return -EACCES;
	return 0;
}

With ctx->sk marked as PTR_TRUSTED in sock_map_iter_reg, a NULL check on
ctx->sk yields a trusted struct sock pointer, which matches struct sock_common
at offset zero and is accepted by the verifier for bpf_sock_destroy().

However, unlike bpf_iter_tcp_seq_show() and bpf_iter_udp_seq_show() which
acquire lock_sock(sk) before running the BPF program, sock_map_seq_show() and
sock_hash_seq_show() in net/core/sock_map.c only hold rcu_read_lock():

sock_map_seq_show() / sock_hash_seq_show()
  -> bpf_iter_run_prog()
       -> bpf_sock_destroy()
            -> sk->sk_prot->diag_destroy(sk, ECONNABORTED)
                 -> tcp_abort() / udp_abort()

Because bpf_iter_run_prog() sets current->bpf_ctx, has_current_bpf_ctx()
returns true inside tcp_abort() and udp_abort(), causing both functions to
skip lock_sock(sk) under the assumption that the BPF context already holds the
socket lock:

net/ipv4/tcp.c:tcp_abort() {
	if (!has_current_bpf_ctx())
		lock_sock(sk);
	...
}

net/ipv4/udp.c:udp_abort() {
	if (!has_current_bpf_ctx())
		lock_sock(sk);
	...
}

For UDP sockets in a sockmap or sockhash, udp_abort() will run
__udp_disconnect() and sk->sk_prot->rehash(sk) with no socket lock held at
all.

For TCP_LISTEN sockets in a sockmap or sockhash, tcp_abort() will execute
tcp_set_state(sk, TCP_CLOSE) -> inet_put_port(sk) and inet_csk_listen_stop(sk)
before bh_lock_sock(sk) without holding lock_sock(sk), racing with concurrent
close() or abort paths.

For established TCP sockets, tcp_abort() will only take bh_lock_sock(sk)
without checking sock_owned_by_user(sk), running tcp_write_queue_purge(sk) and
tcp_done(sk) concurrently with process-context holders of lock_sock(sk). If
this races with __tcp_close() after sock_orphan(sk) sets SOCK_DEAD, both
tcp_done() and __tcp_close() can call inet_csk_destroy_sock(sk), leading to a
double sock_put(sk) and use-after-free.

Should sock_map_seq_show() and sock_hash_seq_show() acquire lock_sock(sk), or
should bpf_sock_destroy() be restricted from running in iter/sockmap?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261102-sockmap-update-limit-iter-v2-0-e96a63c43b39@rbox.co?part=4

  reply	other threads:[~2026-11-02  1:33 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02  1:15 [PATCH RFC v2 0/4] bpf, sockmap: Restrict iter-context sockmap updates to sockmap iterators Michal Luczaj
2026-11-02  1:15 ` [PATCH RFC v2 1/4] selftests/bpf: Remove sockmap update from bpf_iter_unix Michal Luczaj
2026-11-02  1:15 ` [PATCH RFC v2 2/4] bpf, sockmap: Restrict iter-context sockmap updates to iter/sockmap Michal Luczaj
2026-11-02  1:54   ` bot+bpf-ci
2026-11-02  1:16 ` [PATCH RFC v2 3/4] selftests/bpf: Add negative test for sockmap update from non-sockmap iter Michal Luczaj
2026-11-02  1:16 ` [PATCH RFC v2 4/4] bpf: Mark bpf_iter__sockmap::sk as PTR_TRUSTED Michal Luczaj
2026-11-02  1:33   ` sashiko-bot [this message]
2026-11-02  8:54 ` [PATCH RFC v2 0/4] bpf, sockmap: Restrict iter-context sockmap updates to sockmap iterators Michal Luczaj

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-192806@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=mhal@rbox.co \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox