On Sun, 30 Aug 2026 14:40:05 +0000
[email protected] wrote:

> >  static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
> >  {
> >     irqentry_state_t irq_state;
> > +   unsigned long dr7;
> >  
> >     WARN_ON_ONCE(user_mode(regs));
> >  
> > @@ -2118,18 +2119,24 @@ static __always_inline void 
> > exc_machine_check_kernel(struct pt_regs *regs)
> >     if (mca_cfg.initialized && mce_check_crashing_cpu())
> >             return;
> >  
> > +   dr7 = local_db_save();
> 
> [Severity: High]
> Does moving local_db_save() below the early checks in
> exc_machine_check_kernel() expose this early #MC entry code to hardware
> breakpoints?
> 
> If a privileged user sets a hardware data breakpoint on a kernel variable
> accessed here, such as mca_cfg.initialized or variables inside
> mce_check_crashing_cpu(), a #DB exception could fire in kernel mode.

Ah, good catch! This can happen if we introduce wprobe.

> 
> If a Machine Check Exception (#MC) then occurs and preempts the #DB handler,
> it switches to the #MC IST stack. Because local_db_save() is not called
> until after these variable accesses, the code could trigger a nested #DB
> exception.
> 
> Since x86 uses a fixed-size Interrupt Stack Table (IST) for #DB exceptions
> that unconditionally resets the stack pointer to the top of the #DB IST
> stack, wouldn't the nested #DB overwrite the active stack frame of the
> interrupted #DB handler, leading to a fatal crash when it attempts to
> return?
> 
> Could local_db_save() be called at the very beginning of
> exc_machine_check_kernel() to prevent this IST stack corruption?

Yes, I will fix it.

Thanks!

-- 
Masami Hiramatsu (Google) <[email protected]>

Reply via email to