arch/x86/kernel/rethook.c | 5 +++++ 1 file changed, 5 insertions(+)
Smatch reported potential memory corruption in rethook
arch_rethook_trampoline_callback() function.
The warning points to a potential memory corruption in function
arch_rethook_trampoline_callback where struct pt_regs *regs->ss was
being casted to *(unsigned long*) although it is working fine with
architecture x86_64 however it may not work with x86_32 since it is
casting regs->ss to unsigned long. Its comment says it is copying
regs->flag into ss but i don't understand why it is copying it to
a unsigned short which is corrupting memory on 32 bit arch.
Regarding this i needed some advice on finding its solution
because if we need to copy all bytes of flags we need 4 or
8 byte memory but regs->ss is only 2 bytes which is not storing all bytes
of flags in 32 bit arch and also on 64 byte arch it is just relying
on cpu alignment for storing the flags which is also werid so,
far i just added some if def condition so that it only copies 2bytes
if the architecture is 32 bit and cast to unsigned long if it is 64
bit arch.
Signed-off-by: Shi Hao <i.shihao.999@gmail.com>
---
arch/x86/kernel/rethook.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c
index 8a1c0111ae79..5f6ecd6deb4a 100644
--- a/arch/x86/kernel/rethook.c
+++ b/arch/x86/kernel/rethook.c
@@ -89,8 +89,13 @@ __used __visible void arch_rethook_trampoline_callback(struct pt_regs *regs)
* Copy FLAGS to 'pt_regs::ss' so that arch_rethook_trapmoline()
* can do RET right after POPF.
*/
+#ifdef CONFIG_X86_32
+ regs->ss = (unsigned short)regs->flags;
+#else
*(unsigned long *)®s->ss = regs->flags;
+#endif
}
+
NOKPROBE_SYMBOL(arch_rethook_trampoline_callback);
/*
--
2.51.0
On October 25, 2025 4:48:30 AM PDT, Shi Hao <i.shihao.999@gmail.com> wrote: >Smatch reported potential memory corruption in rethook >arch_rethook_trampoline_callback() function. > >The warning points to a potential memory corruption in function >arch_rethook_trampoline_callback where struct pt_regs *regs->ss was >being casted to *(unsigned long*) although it is working fine with >architecture x86_64 however it may not work with x86_32 since it is >casting regs->ss to unsigned long. Its comment says it is copying >regs->flag into ss but i don't understand why it is copying it to >a unsigned short which is corrupting memory on 32 bit arch. > >Regarding this i needed some advice on finding its solution >because if we need to copy all bytes of flags we need 4 or >8 byte memory but regs->ss is only 2 bytes which is not storing all bytes >of flags in 32 bit arch and also on 64 byte arch it is just relying >on cpu alignment for storing the flags which is also werid so, >far i just added some if def condition so that it only copies 2bytes >if the architecture is 32 bit and cast to unsigned long if it is 64 >bit arch. > >Signed-off-by: Shi Hao <i.shihao.999@gmail.com> >--- > arch/x86/kernel/rethook.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/arch/x86/kernel/rethook.c b/arch/x86/kernel/rethook.c >index 8a1c0111ae79..5f6ecd6deb4a 100644 >--- a/arch/x86/kernel/rethook.c >+++ b/arch/x86/kernel/rethook.c >@@ -89,8 +89,13 @@ __used __visible void arch_rethook_trampoline_callback(struct pt_regs *regs) > * Copy FLAGS to 'pt_regs::ss' so that arch_rethook_trapmoline() > * can do RET right after POPF. > */ >+#ifdef CONFIG_X86_32 >+ regs->ss = (unsigned short)regs->flags; >+#else > *(unsigned long *)®s->ss = regs->flags; >+#endif > } >+ > NOKPROBE_SYMBOL(arch_rethook_trampoline_callback); > > /* >-- >2.51.0 > Please don't submit a patch where you are explicitly saying you are blindly following a tool and don't actually understand the code. If you did understand the code, or the architecture, you would know that the ss field is embedded in a larger pointer-sized field.
> Please don't submit a patch where you are explicitly saying you are blindly following a tool and don't actually understand the code. > > If you did understand the code, or the architecture, you would know that the ss field is embedded in a larger pointer-sized field. Hi Peter Well thanks for correcting me .Thank you so much for your time. I regret not thoroughly investigating this matter.appreciate your feedback and if there is anything i could do please let me know i am ready to improve and also sorry for the late response . best regards, shi hao
© 2016 - 2026 Red Hat, Inc.