diff options
| author | Mieczyslaw Nalewaj | 2025-10-28 23:23:02 +0000 |
|---|---|---|
| committer | Robert Marko | 2026-02-24 13:40:39 +0000 |
| commit | 22ccb445e611018ede702e6c0798640353632cce (patch) | |
| tree | 71126ee8cfafc502e0b6a6c8b4c32c15514cfc0f | |
| parent | dfbaf846501b1f17d4ac916bb87ad84773414ed8 (diff) | |
| download | stintel-master.tar.gz | |
On MT7620-class platforms (CONFIG_NET_RALINK_MT7620) we observe sporadic
wrong-jump-targets, kernel oopses, hanging, corrupted backtraces or even
"half-written" instructions when the compiler emits a direct 'jal imm26'
call.
This is triggered in:
- the small random helpers inside get_random_u32_below(), and
- the blkcg_maybe_throttle_current() call in resume_user_mode_work().
This patch forces those two call sites to use an indirect call via
a volatile function pointer (load into register + jalr) when building
for MT7620, avoiding embedding a 26-bit immediate jump target.
Additionally, on MT7620 builds the exec path in fs/exec.c is modified:
- skip arch_align_stack() + PAGE_ALIGN() in setup_arg_pages()
because the micro-randomization (< PAGE_SIZE) implemented by many
ports (including MT7620) is negated immediately by PAGE_ALIGN().
Skipping the redundant PAGE_ALIGN() reduces exposure to the
problematic code pattern.
These changes are targeted workarounds for MT7620; behavioral logic is unchanged.
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
Link: https://github.com/openwrt/openwrt/pull/20553
Signed-off-by: Robert Marko <robimarko@gmail.com>
3 files changed, 137 insertions, 0 deletions
diff --git a/target/linux/ramips/patches-6.12/330-mt7620-avoid-direct-jal-in-random-helper.patch b/target/linux/ramips/patches-6.12/330-mt7620-avoid-direct-jal-in-random-helper.patch new file mode 100644 index 0000000000..c65b417f91 --- /dev/null +++ b/target/linux/ramips/patches-6.12/330-mt7620-avoid-direct-jal-in-random-helper.patch @@ -0,0 +1,72 @@ +From: Mieczyslaw Nalewaj <namiltd@yahoo.com> +Date: Sun, 26 Oct 2025 10:36:02 +0100 +Subject: [PATCH] mt7620: avoid direct jal imm26 in random helper + +This patch forces an indirect call (via a function pointer) on the mt7620 +platform when calling the small random helpers used by the constant-folding +fast path of get_random_u32_below(). That avoids embedding a 26-bit immediate +jump target in a direct `jal` instruction, which on affected platforms can +lead to sporadic incorrect jump targets, intermittent oopses/crashes/hangs, +corrupted backtraces, or "half-written" instructions under some circumstances. + +The change is targetted and conservative: it only alters code generation on +CONFIG_NET_RALINK_MT7620 builds and does not change the algorithmic behaviour +of get_random_u32_below(). + +Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com> +--- + a/include/linux/random.h | 36 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 32 insertions(+), 4 deletions(-) + +--- a/include/linux/random.h ++++ b/include/linux/random.h +@@ -73,17 +73,45 @@ static inline u32 get_random_u32_below(u + BUILD_BUG_ON_MSG(!ceil, "get_random_u32_below() must take ceil > 0"); + if (ceil <= 1) + return 0; +- for (;;) { +- if (ceil <= 1U << 8) { ++ if (ceil <= 1U << 8) { ++#ifdef CONFIG_NET_RALINK_MT7620 ++ typedef u8 (*getrnd_t)(void); ++ volatile getrnd_t rnd_fn = (getrnd_t)get_random_u8; ++#endif ++ for (;;) { ++#ifdef CONFIG_NET_RALINK_MT7620 ++ u32 mult = ceil * rnd_fn(); ++#else + u32 mult = ceil * get_random_u8(); ++#endif + if (likely(is_power_of_2(ceil) || (u8)mult >= (1U << 8) % ceil)) + return mult >> 8; +- } else if (ceil <= 1U << 16) { ++ } ++ } else if (ceil <= 1U << 16) { ++#ifdef CONFIG_NET_RALINK_MT7620 ++ typedef u16 (*getrnd_t)(void); ++ volatile getrnd_t rnd_fn = (getrnd_t)get_random_u16; ++#endif ++ for (;;) { ++#ifdef CONFIG_NET_RALINK_MT7620 ++ u32 mult = ceil * rnd_fn(); ++#else + u32 mult = ceil * get_random_u16(); ++#endif + if (likely(is_power_of_2(ceil) || (u16)mult >= (1U << 16) % ceil)) + return mult >> 16; +- } else { ++ } ++ } else { ++#ifdef CONFIG_NET_RALINK_MT7620 ++ typedef u32 (*getrnd_t)(void); ++ volatile getrnd_t rnd_fn = (getrnd_t)get_random_u32; ++#endif ++ for (;;) { ++#ifdef CONFIG_NET_RALINK_MT7620 ++ u64 mult = (u64)ceil * rnd_fn(); ++#else + u64 mult = (u64)ceil * get_random_u32(); ++#endif + if (likely(is_power_of_2(ceil) || (u32)mult >= -ceil % ceil)) + return mult >> 32; + } diff --git a/target/linux/ramips/patches-6.12/331-mt7620-avoid-direct-jal-in-resume_user_mode_work.patch b/target/linux/ramips/patches-6.12/331-mt7620-avoid-direct-jal-in-resume_user_mode_work.patch new file mode 100644 index 0000000000..d501734bf8 --- /dev/null +++ b/target/linux/ramips/patches-6.12/331-mt7620-avoid-direct-jal-in-resume_user_mode_work.patch @@ -0,0 +1,35 @@ +From: Mieczyslaw Nalewaj <namiltd@yahoo.com> +Date: Tue, 28 Oct 2025 22:50:41 +0100 +Subject: [PATCH] mt7620: avoid direct jal imm26 in resume_user_mode_work + +This patch forces an indirect call (via a function pointer) on the mt7620 +platform when invoking blkcg_maybe_throttle_current() from +resume_user_mode_work(). Avoiding a direct `jal` with a 26-bit immediate +jump target prevents sporadic incorrect jump targets / intermittent oopses, +crashes or hanging behavior that can appear on affected platforms. + +The change is targeted: it only alters the call site when CONFIG_NET_RALINK_MT7620 +is enabled and does not change the functional behaviour of resume_user_mode_work(). + +Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com> + +--- + a/include/linux/resume_user_mode.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/include/linux/resume_user_mode.h ++++ b/include/linux/resume_user_mode.h +@@ -57,7 +57,13 @@ static inline void resume_user_mode_work + #endif + + mem_cgroup_handle_over_high(GFP_KERNEL); ++#ifdef CONFIG_NET_RALINK_MT7620 ++ typedef void (*bmtc_t)(void); ++ volatile bmtc_t bmtc_fn = (bmtc_t)blkcg_maybe_throttle_current; ++ bmtc_fn(); ++#else + blkcg_maybe_throttle_current(); ++#endif + + rseq_handle_notify_resume(NULL, regs); + } diff --git a/target/linux/ramips/patches-6.12/332-mt7620-conditional-stack-align.patch b/target/linux/ramips/patches-6.12/332-mt7620-conditional-stack-align.patch new file mode 100644 index 0000000000..37b2b19657 --- /dev/null +++ b/target/linux/ramips/patches-6.12/332-mt7620-conditional-stack-align.patch @@ -0,0 +1,30 @@ +From: Mieczyslaw Nalewaj <namiltd@yahoo.com> +Date: Sun, 26 Oct 2025 10:36:02 +0100 +Subject: [PATCH] mt7620: conditional stack align + +This patch avoids applying arch_align_stack() and PAGE_ALIGN() in the exec +path on CONFIG_NET_RALINK_MT7620 builds. Many ports (including mt7620) +implement only micro-randomization inside arch_align_stack() (random offset +< PAGE_SIZE and then align-down to small alignment). Callers that immediately +apply PAGE_ALIGN() will round that micro-offset back to the original page +boundary, so invoking arch_align_stack() then PAGE_ALIGN() is pointless and +can be avoided on the affected platform. + +Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com> +--- + a/fs/exec.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -750,8 +750,10 @@ int setup_arg_pages(struct linux_binprm + mm->arg_start = bprm->p - stack_shift; + bprm->p = vma->vm_end - stack_shift; + #else ++#ifndef CONFIG_NET_RALINK_MT7620 + stack_top = arch_align_stack(stack_top); + stack_top = PAGE_ALIGN(stack_top); ++#endif + + if (unlikely(stack_top < mmap_min_addr) || + unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr)) |