lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260107235724.28101-1-aidan@aktech.ai>
Date: Wed,  7 Jan 2026 19:57:23 -0400
From: Aidan Khoury <aidan@...ech.ai>
To: linux-kernel@...r.kernel.org,
	kvm@...r.kernel.org
Cc: Sean Christopherson <seanjc@...gle.com>,
	Paolo Bonzini <pbonzini@...hat.com>,
	Thomas Gleixner <tglx@...utronix.de>,
	Ingo Molnar <mingo@...hat.com>,
	Borislav Petkov <bp@...en8.de>,
	Dave Hansen <dave.hansen@...ux.intel.com>,
	x86@...nel.org,
	"H. Peter Anvin" <hpa@...or.com>,
	Aidan Khoury <aidan@...ers.engineering>,
	Nick Peterson <everdox@...il.com>,
	Aidan Khoury <aidan@...ech.ai>
Subject: [PATCH v1 0/1] KVM: x86: Merge pending debug causes when vectoring #DB

This is a single patch that fixes incorrect guest DR6 contents when KVM
vectors #DB on Intel VMX in the presence of deferred debug causes recorded
in VMCS.GUEST_PENDING_DBG_EXCEPTIONS.

See Intel SDM Vol. 3C, 27.3.1.5 Checks on Guest Non-Register State
and Intel SDM Vol. 3C, 27.7.3 Delivery of Pending Debug Exceptions after VM Entry

Intel VMX defers certain debug exception causes in the VMCS field
GUEST_PENDING_DBG_EXCEPTIONS (B0-B3, enabled breakpoint, BS, RTM). This
state is used when debug exceptions are suppressed due to interrupt
shadow (e.g. MOV SS/POP SS or STI), and the deferred causes are later
combined with other debug reasons when #DB is ultimately delivered.

KVM may vector an in-kernel #DB after a VM-exit and/or instruction
emulation. A concrete example is a guest that:

  - programs a data breakpoint (B0) on an operand used by MOV SS
  - enables single-step (RFLAGS.TF)
  - executes MOV SS (data breakpoint triggers, #DB is suppressed)
  - executes an instruction that VM-exits and is emulated (e.g. CPUID),
    or executes ICEBP/INT1 which is intercepted as #DB

On bare metal, guest DR6 reports the combined reasons (e.g. BS+B0). In
KVM/VMX, the deferred breakpoint cause is recorded in
GUEST_PENDING_DBG_EXCEPTIONS while KVM generates a #DB for single-step,
but the queued #DB payload delivered to guest DR6 can omit the pending
causes. This results in guest DR6 missing B0-B3 even though the CPU
would report them.

Fix this by merging pending causes from GUEST_PENDING_DBG_EXCEPTIONS into
the #DB payload when delivering the exception payload to guest state.
The merge is performed in kvm_deliver_exception_payload() so it applies
to both the normal injection path and the !guest_mode path where the
payload may be consumed immediately by kvm_multiple_exception().

To keep x86 core code vendor-agnostic, add an optional x86 op
get_pending_dbg_exceptions() that returns the relevant pending-debug
bits for the active vendor. VMX implements the hook by reading
VMCS.GUEST_PENDING_DBG_EXCEPTIONS and masking to architecturally defined
bits; other vendors return 0.

After this change, guests observe all accumulated #DB causes in DR6 when
#DB is vectored, matching bare-metal behavior.

Tested on Intel host with KVM/VMX enabled by running the tiny repro asm below
inside a Windows guest. On bare metal, DR6 reports both BS and B0. Under KVM/VMX
without this patch, DR6 may report BS but miss B0.

A minimal reproducer in the guest:
  - use ptrace (or veh+SetThreadContext on windows) for handling #DB traps and managing DRs
  - Prime DR0 and DR7 to a memory operand used by MOV SS (data breakpoint, enabled)
  - execute MOV SS from that memory operand (breakpoint met, delivery suppressed)
  - execute CPUID (emulated) or ICEBP/INT1 (intercepted)
  - In the #DB handler, read DR6 to observe the reported causes

```
__asm__ __volatile__(
	"pushq %%rbx\n"
	"pushfq\n"
	"orl $0x100, (%%rsp)\n"    /* set TF in saved RFLAGS on stack */
	"popfq\n"
	"movw (%0), %%ss\n"        /* load SS from probe page */
	"cpuid\n"                  /* trigger intercepting instruction (cpuid in this case) */
	"popq %%rbx\n"             /* #DB fires here with DR6 missing B0 under KVM/VMX pre-patch */
	: : "r"(&ss_probe) : "rax", "rcx", "rdx", "memory"
);
```

Reproducer PoC: https://github.com/ajkhoury/kvm-guest-anomalies

Aidan Khoury (1):
  KVM: x86: Merge pending debug causes when vectoring #DB

 arch/x86/include/asm/kvm-x86-ops.h |  1 +
 arch/x86/include/asm/kvm_host.h    |  1 +
 arch/x86/kvm/vmx/main.c            |  9 +++++++++
 arch/x86/kvm/vmx/vmx.c             | 16 +++++++++++-----
 arch/x86/kvm/vmx/x86_ops.h         |  1 +
 arch/x86/kvm/x86.c                 | 12 ++++++++++++
 6 files changed, 35 insertions(+), 5 deletions(-)

-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ