> diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
> index 93156ac4f..b08c95872 100644
> --- a/arch/x86/include/asm/ftrace.h
> +++ b/arch/x86/include/asm/ftrace.h
> @@ -56,6 +56,11 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs)
>       return &arch_ftrace_regs(fregs)->regs;
>  }
>
> +#define arch_ftrace_partial_regs(regs) do {  \
> +     regs->flags &= ~X86_EFLAGS_FIXED;       \
> +     regs->cs = __KERNEL_CS;                 \
> +} while (0)
> +

Can arch_ftrace_partial_regs read uninitialized regs->flags?

In return_to_handler, the ftrace_regs structure is allocated on the
stack but only a few fields are initialized (RAX, RDX, RBP, RSP).
The EFLAGS/flags field is never written before
arch_ftrace_partial_regs reads it:

arch/x86/kernel/ftrace_64.S return_to_handler:
    subq $(FRAME_SIZE), %rsp    # Allocate ftrace_regs on stack
    movq %rax, RAX(%rsp)
    movq %rdx, RDX(%rsp)
    movq %rbp, RBP(%rsp)
    movq %rsp, RSP(%rsp)
    # No initialization of EFLAGS field

Then ftrace_partial_regs()->arch_ftrace_partial_regs() executes:
    regs->flags &= ~X86_EFLAGS_FIXED;

This reads the uninitialized flags field. Stack allocations contain
garbage, so regs->flags will have whatever data was previously on
the stack. The &= operation produces undefined results when operating
on uninitialized memory.

For comparison, ftrace_regs_caller explicitly initializes EFLAGS:
    movq MCOUNT_REG_SIZE(%rsp), %rcx
    movq %rcx, EFLAGS(%rsp)

Should return_to_handler initialize regs->flags to 0 (or another
appropriate value) before arch_ftrace_partial_regs modifies it?

[ ... ]

---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/19051288274

Reply via email to