From: sashiko-bot@kernel.org
To: "Pawan Gupta" <pawan.kumar.gupta@linux.intel.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH 6.12.y 3/6] bpf: Restrict JIT predictor flush to cBPF
Date: Wed, 15 Jul 2026 21:56:50 +0000 [thread overview]
Message-ID: <20260715215650.E98FA1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260715-cbpf-jit-spray-hardening-6-12-y-v1-3-d8585a9aed80@linux.intel.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Restricting the JIT predictor flush to only cBPF programs breaks the BHI / Spectre v2 memory-reuse mitigation for privileged victim programs.
- [High] JIT predictor flush is skipped for unprivileged native eBPF programs, bypassing JIT spraying and BTB hardening when `kernel.unprivileged_bpf_disabled=0`.
- [Medium] The `pr_warn_once` warning for missing predictor flushes on large allocations is dead code and masks a violation of the security assumption.
--
--- Patch [3]: [PATCH 6.12.y 3/6] bpf: Restrict JIT predictor flush to cBPF ---
commit 0786ec970d8b751f7c4716434c9231f6d505e991
Author: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
bpf: Restrict JIT predictor flush to cBPF
This patch restricts the BPF JIT predictor flush on memory reuse to only
cBPF programs. It assumes that only cBPF programs can be loaded by
unprivileged users, skipping the flush for eBPF allocations, trampolines,
and dispatchers to improve performance.
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 8cbc26081bdb2..4304596c8fddd 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
[ ... ]
> @@ -3206,7 +3206,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
>
> void *arch_alloc_bpf_trampoline(unsigned int size)
> {
> - return bpf_prog_pack_alloc(size, jit_fill_hole);
> + return bpf_prog_pack_alloc(size, jit_fill_hole, false);
[Severity: High]
Does hardcoding was_classic to false here leave trampoline allocations
vulnerable to BTB poisoning on memory reuse?
If an unprivileged attacker previously poisoned the BTB for this virtual
address, skipping the flush could cause the highly privileged trampoline to
inherit the poisoned BTB.
> }
>
> void arch_free_bpf_trampoline(void *image, unsigned int size)
[ ... ]
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 5f676320c53be..29d39092c4577 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
[ ... ]
> @@ -967,7 +967,7 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> * safe because cBPF programs (the unprivileged attack surface)
> * are bounded well below a pack size.
> */
> - if (static_branch_unlikely(&bpf_pred_flush_enabled))
> + if (was_classic && static_branch_unlikely(&bpf_pred_flush_enabled))
> pr_warn_once("BPF: Predictors not flushed for allocations greater than BPF_PROG_PACK_SIZE\n");
[Severity: Medium]
Is this condition logically possible? Since cBPF programs are strictly
limited to 4096 instructions, they can never generate a JIT image exceeding
the BPF_PROG_PACK_SIZE (typically 2MB).
Additionally, if unprivileged native eBPF programs are enabled, they could
exceed the pack size but would silently bypass this warning because
was_classic is false, potentially masking that the unprivileged attack
surface is not bounded below a pack size.
> size = round_up(size, PAGE_SIZE);
> ptr = bpf_jit_alloc_exec(size);
> @@ -999,7 +999,9 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
> pos = 0;
>
> found_free_area:
> - static_call_cond(bpf_arch_pred_flush)();
> + /* Flush only for cBPF as it may contain a crafted gadget */
> + if (static_branch_unlikely(&bpf_pred_flush_enabled) && was_classic)
> + static_call_cond(bpf_arch_pred_flush)();
[Severity: High]
Does skipping the flush for eBPF allocations defeat the BHI / Spectre v2
mitigation for privileged victim programs?
If an unprivileged attacker loads a cBPF program, poisons the BTB for its
virtual addresses, and frees it, the predictor flush is required to protect
the subsequent program allocated at the same address. By skipping the
flush when the new allocation is eBPF, the privileged victim program
might inherit the attacker's poisoned BTB.
[Severity: High]
Also, does this leave native eBPF programs vulnerable to JIT spraying when
kernel.unprivileged_bpf_disabled=0?
Native eBPF programs loaded by unprivileged users will evaluate to false
for bpf_prog_was_classic() in include/linux/filter.h. This causes the
allocator to skip the predictor flush, potentially bypassing the JIT spraying
and BTB hardening for unprivileged native eBPF programs.
> bitmap_set(pack->bitmap, pos, nbits);
> ptr = (void *)(pack->ptr) + (pos << BPF_PROG_CHUNK_SHIFT);
>
[ ... ]
> diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
> index b77db7413f8c7..ea2d60dc1feeb 100644
> --- a/kernel/bpf/dispatcher.c
> +++ b/kernel/bpf/dispatcher.c
> @@ -145,7 +145,7 @@ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
>
> mutex_lock(&d->mutex);
> if (!d->image) {
> - d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero);
> + d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero, false);
[Severity: High]
Does hardcoding was_classic to false here introduce the same mitigation bypass
for dispatchers as seen with the trampoline allocations?
Dispatcher allocations are highly privileged and contain indirect branches.
Skipping the flush on memory reuse might allow them to inherit a poisoned BTB.
> if (!d->image)
> goto out;
> d->rw_image = bpf_jit_alloc_exec(PAGE_SIZE);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260715-cbpf-jit-spray-hardening-6-12-y-v1-0-d8585a9aed80@linux.intel.com?part=3
next prev parent reply other threads:[~2026-07-15 21:56 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-15 21:27 [PATCH 6.12.y 0/6] cBPF JIT spray hardening Pawan Gupta
2026-07-15 21:27 ` [PATCH 6.12.y 1/6] bpf: Support for hardening against JIT spraying Pawan Gupta
2026-07-15 21:46 ` sashiko-bot
2026-07-15 21:28 ` [PATCH 6.12.y 2/6] x86/bugs: Enable IBPB flush on BPF JIT allocation Pawan Gupta
2026-07-15 21:44 ` sashiko-bot
2026-07-15 21:28 ` [PATCH 6.12.y 3/6] bpf: Restrict JIT predictor flush to cBPF Pawan Gupta
2026-07-15 21:56 ` sashiko-bot [this message]
2026-07-15 21:28 ` [PATCH 6.12.y 4/6] bpf: Skip redundant IBPB in pack allocator Pawan Gupta
2026-07-15 21:28 ` [PATCH 6.12.y 5/6] bpf: Prefer packs that won't trigger an IBPB flush on allocation Pawan Gupta
2026-07-15 21:29 ` [PATCH 6.12.y 6/6] bpf: Prefer dirty packs for eBPF allocations Pawan Gupta
2026-07-15 21:44 ` sashiko-bot
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=20260715215650.E98FA1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=pawan.kumar.gupta@linux.intel.com \
--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