All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: Sanghyun Park <sanghyun.park.cnu@gmail.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>
Cc: Sun Jian <sun.jian.kdev@gmail.com>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Song Liu <song@kernel.org>,
	Yonghong Song <yonghong.song@linux.dev>,
	Jiri Olsa <jolsa@kernel.org>,
	Emil Tsalapatis <emil@etsalapatis.com>,
	Puranjay Mohan <puranjay@kernel.org>,
	bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
	syzbot+cdd6c0925e12b0af60cc@syzkaller.appspotmail.com,
	sashiko-bot@kernel.org
Subject: Re: [PATCH bpf-next] bpf: Fix mmap_lock leak in irq_work path
Date: Wed, 29 Jul 2026 13:03:45 -0700	[thread overview]
Message-ID: <33024de2-1121-4f08-a579-8a9ceeddf8bd@linux.dev> (raw)
In-Reply-To: <20260722023004.1497923-2-sanghyun.park.cnu@gmail.com>

On 2026-07-21 7:30 p.m., Sanghyun Park wrote:
> stack_map_get_build_id_offset() introduced a per-CPU irq_work to defer
> mmap_read_unlock() from NMI context, and bpf_find_vma() later reused the
> same mmap_unlock_work. Both callers only check whether the work is busy
> before taking mmap_lock, so a nested caller can reuse the slot before the
> first caller queues it. Two read locks may then be acquired while only one
> deferred unlock runs, leaking a read lock and blocking exit_mmap().
> 
> Reserve the per-CPU slot before mmap_read_trylock(). Use the same wrapper
> in stackmap and bpf_find_vma() so both callers release the reservation on
> trylock failure. Release it after the irq_work callback unlocks the mm.

Hi Sanghyun,

Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>

The fix looks correct to me, thanks!
Just one non-blocking nit below.

> 
> Fixes: bae77c5eb5b2 ("bpf: enable stackmap with build_id in nmi context")
> Reported-by: syzbot+cdd6c0925e12b0af60cc@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=cdd6c0925e12b0af60cc
> Reported-by: sashiko-bot@kernel.org
> Closes: https://lore.kernel.org/r/20260630033745.B80201F000E9@smtp.kernel.org
> Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
> ---
>   kernel/bpf/mmap_unlock_work.h | 37 +++++++++++++++++++++++++++++++----
>   kernel/bpf/stackmap.c         |  3 +--
>   kernel/bpf/task_iter.c        |  7 +++----
>   3 files changed, 37 insertions(+), 10 deletions(-)
> 
> diff --git a/kernel/bpf/mmap_unlock_work.h b/kernel/bpf/mmap_unlock_work.h
> index 5d18d7d85bef9..d416e4337635f 100644
> --- a/kernel/bpf/mmap_unlock_work.h
> +++ b/kernel/bpf/mmap_unlock_work.h
> @@ -4,12 +4,14 @@
>   
>   #ifndef __MMAP_UNLOCK_WORK_H__
>   #define __MMAP_UNLOCK_WORK_H__
> +#include <linux/atomic.h>
>   #include <linux/irq_work.h>
>   
>   /* irq_work to run mmap_read_unlock() in irq_work */
>   struct mmap_unlock_irq_work {
>   	struct irq_work irq_work;
>   	struct mm_struct *mm;
> +	atomic_t active;
>   };
>   
>   DECLARE_PER_CPU(struct mmap_unlock_irq_work, mmap_unlock_work);
> @@ -18,8 +20,8 @@ DECLARE_PER_CPU(struct mmap_unlock_irq_work, mmap_unlock_work);
>    * We cannot do mmap_read_unlock() when the irq is disabled, because of
>    * risk to deadlock with rq_lock. To look up vma when the irqs are
>    * disabled, we need to run mmap_read_unlock() in irq_work. We use a
> - * percpu variable to do the irq_work. If the irq_work is already used
> - * by another lookup, we fall over.
> + * percpu variable to do the irq_work. The active flag reserves the slot
> + * before mmap_read_trylock() and until the irq_work callback consumes mm.
>    */
>   static inline bool bpf_mmap_unlock_get_irq_work(struct mmap_unlock_irq_work **work_ptr)
>   {
> @@ -29,9 +31,10 @@ static inline bool bpf_mmap_unlock_get_irq_work(struct mmap_unlock_irq_work **wo
>   	if (irqs_disabled()) {
>   		if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
>   			work = this_cpu_ptr(&mmap_unlock_work);
> -			if (irq_work_is_busy(&work->irq_work)) {
> -				/* cannot queue more up_read, fallback */
> +			if (irq_work_is_busy(&work->irq_work) ||
> +			    atomic_cmpxchg_acquire(&work->active, 0, 1)) {

It appears you could use the `active` guard exclusively to cover the
leak.

It is taken before the trylock and cleared only at the end of the
callback. So can irq_work_is_busy(&work->irq_work) be dropped here?


>   				irq_work_busy = true;
> +				work = NULL;
>   			}
>   		} else {
>   			/*
> [...]

  parent reply	other threads:[~2026-07-29 20:04 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-22  2:30 [PATCH bpf-next] bpf: Fix mmap_lock leak in irq_work path Sanghyun Park
2026-07-22  6:24 ` sun jian
2026-07-29 16:58 ` Puranjay Mohan
2026-07-29 20:03 ` Ihor Solodrai [this message]
2026-07-30  5:17   ` Sanghyun Park

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=33024de2-1121-4f08-a579-8a9ceeddf8bd@linux.dev \
    --to=ihor.solodrai@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=puranjay@kernel.org \
    --cc=sanghyun.park.cnu@gmail.com \
    --cc=sashiko-bot@kernel.org \
    --cc=song@kernel.org \
    --cc=sun.jian.kdev@gmail.com \
    --cc=syzbot+cdd6c0925e12b0af60cc@syzkaller.appspotmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.