BPF List
 help / color / mirror / Atom feed
From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: Jan-Gerd Tenberge <janten@gmail.com>, bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com,
	jakub@cloudflare.com, edumazet@kernel.org, kuniyu@google.com,
	pabeni@redhat.com, willemb@google.com, davem@davemloft.net,
	kuba@kernel.org, horms@kernel.org, yonghong.song@linux.dev,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH bpf] bpf, sockmap: Fix UAF when map user reference is revived
Date: Mon, 12 Oct 2026 09:59:22 +0800	[thread overview]
Message-ID: <06f54345-4ca6-455f-9519-138e0b6db24b@linux.dev> (raw)
In-Reply-To: <20261008095656.92793-1-janten@gmail.com>


On 10/8/26 5:56 PM, Jan-Gerd Tenberge wrote:
> bpf_map_put_uref() invokes map_release_uref after usercnt reaches zero,
> before bpf_map_put() drops the map reference. BPF_MAP_GET_FD_BY_ID can
> find the map during that callback and raise usercnt again.
>
> The sockmap and sockhash release callbacks unconditionally drop programs
> without taking sockmap_mutex. A concurrent attach through the revived fd
> can therefore publish a new program before the stale callback drops it.
>
> For a bpf_link attachment, this leaves plink set while pprog is NULL, so
> link release warns and leaves the attachment slot unusable. The callback
> can also drop the program between sock_map_prog_update() and the later
> bpf_prog_inc(). If the program fd is closed concurrently, this removes
> the last reference and schedules an RCU free. The subsequent increment
> then resurrects a zero reference and leaves link->prog pointing to memory
> that will be freed. A KASAN reproducer triggers a slab-use-after-free when
> reading information from that link.
>
> Triggering the race requires CAP_SYS_ADMIN in the initial user namespace,
> because reviving the map uses BPF_MAP_GET_FD_BY_ID. A deterministic KASAN
> reproducer is available privately on request. It was used to verify the
> UAF before this change and its absence afterwards.
>
> Serialize the release callbacks with program updates using sockmap_mutex
> and recheck usercnt under the mutex. If the map was revived, leave its
> programs intact. Move the map user-reference put in link release outside
> the mutex to avoid recursively taking sockmap_mutex when it drops the last
> user reference.
>
> Fixes: 699c23f02c65 ("bpf: Add bpf_link support for sk_msg and sk_skb progs")
> Assisted-by: LLM
> Cc: stable@vger.kernel.org
> Signed-off-by: Jan-Gerd Tenberge <janten@gmail.com>


Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>


> ---
>   net/core/sock_map.c | 18 ++++++++++++++----
>   1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/net/core/sock_map.c b/net/core/sock_map.c
> index 38df84284328..32ccf4ca3c76 100644
> --- a/net/core/sock_map.c
> +++ b/net/core/sock_map.c
> @@ -26,7 +26,8 @@ struct bpf_stab {
>   
>   /* This mutex is used to
>    *  - protect race between prog/link attach/detach and link prog update, and
> - *  - protect race between releasing and accessing map in bpf_link.
> + *  - protect race between releasing and accessing map in bpf_link, and
> + *  - protect race between map user-reference release and prog/link updates.
>    * A single global mutex lock is used since it is expected contention is low.
>    */
>   static DEFINE_MUTEX(sockmap_mutex);
> @@ -372,7 +373,10 @@ static void sock_map_free(struct bpf_map *map)
>   
>   static void sock_map_release_progs(struct bpf_map *map)
>   {
> -	psock_progs_drop(&container_of(map, struct bpf_stab, map)->progs);
> +	mutex_lock(&sockmap_mutex);
> +	if (!atomic64_read(&map->usercnt))
> +		psock_progs_drop(&container_of(map, struct bpf_stab, map)->progs);
> +	mutex_unlock(&sockmap_mutex);
>   }
>   
>   static struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
> @@ -1226,7 +1230,10 @@ static void *sock_hash_lookup(struct bpf_map *map, void *key)
>   
>   static void sock_hash_release_progs(struct bpf_map *map)
>   {
> -	psock_progs_drop(&container_of(map, struct bpf_shtab, map)->progs);
> +	mutex_lock(&sockmap_mutex);
> +	if (!atomic64_read(&map->usercnt))
> +		psock_progs_drop(&container_of(map, struct bpf_shtab, map)->progs);
> +	mutex_unlock(&sockmap_mutex);
>   }
>   
>   BPF_CALL_4(bpf_sock_hash_update, struct bpf_sock_ops_kern *, sops,
> @@ -1743,6 +1750,7 @@ struct sockmap_link {
>   static void sock_map_link_release(struct bpf_link *link)
>   {
>   	struct sockmap_link *sockmap_link = container_of(link, struct sockmap_link, link);
> +	struct bpf_map *map = NULL;
>   
>   	mutex_lock(&sockmap_mutex);
>   	if (!sockmap_link->map)
> @@ -1751,10 +1759,12 @@ static void sock_map_link_release(struct bpf_link *link)
>   	WARN_ON_ONCE(sock_map_prog_update(sockmap_link->map, NULL, link->prog, link,
>   					  link->attach_type));
>   
> -	bpf_map_put_with_uref(sockmap_link->map);
> +	map = sockmap_link->map;
>   	sockmap_link->map = NULL;
>   out:
>   	mutex_unlock(&sockmap_mutex);
> +	if (map)
> +		bpf_map_put_with_uref(map);
>   }
>   
>   static int sock_map_link_detach(struct bpf_link *link)
>
> base-commit: ff47652a4b66c067c765a7ad464d930b5a9367cc

  reply	other threads:[~2026-10-12  1:59 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-08  9:56 [PATCH bpf] bpf, sockmap: Fix UAF when map user reference is revived Jan-Gerd Tenberge
2026-10-12  1:59 ` Jiayuan Chen [this message]
2026-10-12  9:04 ` Jakub Sitnicki

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=06f54345-4ca6-455f-9519-138e0b6db24b@linux.dev \
    --to=jiayuan.chen@linux.dev \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=jakub@cloudflare.com \
    --cc=janten@gmail.com \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=stable@vger.kernel.org \
    --cc=willemb@google.com \
    --cc=yonghong.song@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