Re: [PATCH] LoongArch: kprobes: Avoid preempt count underflow without probe

From: Bradley Morgan

Date: Sun Aug 23 2026 - 17:26:16 EST


On 23 August 2026 22:18:23 BST, "Jérémy Jean"
<Jeremy.Jean@xxxxxxxxxxxxxxxxx> wrote:
>LoongArch uses break 11 for the breakpoint placed after an instruction
>that Kprobes executes out of line. Since userspace can issue the same
>break instruction, do_bp() can reach kprobe_singlestep_handler() when
>there is no current probe.
>

Intresting

>The handler returns false in this case, but first calls
>preempt_enable_no_resched(). The corresponding preempt_disable() is done
>by kprobe_breakpoint_handler() on a real Kprobe hit, so it has not run
>here. As a result, an ordinary userspace breakpoint underflows the
>current task's preempt count.
>

checked. Guess that's true

>This also makes in_interrupt() return true until the task schedules. One
>visible consequence is socket cgroup attribution: cgroup_sk_alloc()
>treats the allocation as interrupt context and assigns the socket to the
>root cgroup. A socket opened from the SIGTRAP handler can then avoid a
>BPF_CGROUP_INET_SOCK_CREATE policy attached to the task's own cgroup.
>
>Return as soon as kprobe_running() reports no active probe.
>

Ideal.

>The same check appeared in [PATCH v10 2/4] of the original LoongArch
>Kprobes series, but was dropped before the feature reached mainline.
>

wonder why.

>Link: https://patchew.org/linux/1670575981-14389-1-git-send-email-yangtiezhu%40loongson.cn/1670575981-14389-3-git-send-email-yangtiezhu%40loongson.cn/

Lore please.

>Fixes: 6d4cc40fb5f5 ("LoongArch: Add kprobes support")
>Assisted-by: Codex:gpt-5

5.6-sol? Or normal GPT 5?

>Signed-off-by: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
>---
> arch/loongarch/kernel/kprobes.c | 3 +++
> 1 file changed, 3 insertions(+)
>
>diff --git a/arch/loongarch/kernel/kprobes.c b/arch/loongarch/kernel/kprobes.c
>index 1985ed30dd16f..ddfefea174727 100644
>--- a/arch/loongarch/kernel/kprobes.c
>+++ b/arch/loongarch/kernel/kprobes.c
>@@ -275,6 +275,9 @@ bool kprobe_singlestep_handler(struct pt_regs *regs)
> struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> unsigned long addr = instruction_pointer(regs);
>
>+ if (!cur)
>+ return false;


comment?

/* do_bp() can reach
* kprobe_singlestep_handler() when
* there is no current probe, which
* may cause issues.
*/

My one isn't perfect, but feel free to bikeshed


Well, I'm not a loongarch expert, but I am good with kprobes, hence this
review.


>+
> if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
> ((unsigned long)&cur->ainsn.insn[1] == addr)) {
> restore_local_irqflag(kcb, regs);
>

Thanks!