# DF-1315 — AMD-SVM guest debug registers persist in host context (nvmm)

## Verdict
**NOT TESTABLE AT RUNTIME on this guest — confirmed real latent vulnerability in source.**

## Mechanism (confirmed by source trace)
`sys/dev/virtual/nvmm/x86/nvmm_x86_svm.c` is DragonFly's NVMM AMD-SVM backend.

AMD **SVM does not save/restore host debug registers across VMRUN/#VMEXIT**
(there is no host-save-area field for DR0–DR7, unlike Intel VMX's VMCS host
state).  NVMM relies on software save/restore around the VMRUN:

- `svm_vcpu_guest_dbregs_enter()` (line 1486):
  - calls `x86_curthread_save_dbregs(cpudata->hstate.drs)` — but the DragonFly
    version (`nvmm_x86_internal.h:142`) **early-returns without saving** when
    `PCB_DBREGS` is unset (the common case), so host DR7 is *not* captured;
  - then `x86_set_dr7(0)` and loads guest DR0–DR3 into hardware.
- VMRUN runs the guest.  With `intercept_dr` clear (no DR interception), the
  guest's `MOV DR7` writes go straight to hardware DR7, and a guest can arm a
  **data breakpoint on a host kernel address** in DR0 + DR7.
- `svm_vcpu_guest_dbregs_leave()` (line 1500):
  - saves guest DR0–DR3;
  - calls `x86_curthread_restore_dbregs(cpudata->hstate.drs)` — which again
    **early-returns without touching DR7** when `PCB_DBREGS` is unset.  So the
    guest-armed DR7 **stays loaded** after #VMEXIT, and DR0 still holds the
    guest's chosen address.

Net effect: a guest under nvmm (AMD-SVM) can leave a hardware data breakpoint
armed on a host address that persists into the host's execution context, so the
next host code touching that address takes an unexpected `#DB` → host DoS (or
worse, depending on host `#DB` handling).  This is a host/guest isolation break.

## Why it does not reproduce on this guest
- The guest CPU reports **no AMD-SVM** feature:
  `AMD Features=0x20100800<SYSCALL,NX,LM>` — the SVM bit (0x1000) is absent.
  NVMM's SVM backend will not initialise (no usable SVM), so the VMRUN path
  cannot be exercised, even if `nvmm.ko` were loaded (it is not in GENERIC and
  not loaded).
- `nvmm` is a `pseudo-device` listed only in `LINT64`, not in
  `X86_64_GENERIC`.

## Severity / realistic ceiling
On an AMD host with SVM, with nvmm available and a VM run by a user able to
open `/dev/nvmm`, a malicious guest can poison the host's debug registers and
induce host-side `#DB` faults — a host DoS / isolation break (the finding's
CVSS reflects AV:L/AC:L/PR:L/S:C/A:H).  Requires SVM hardware + nvmm access
(often root-only to load the module / create a VM).

## Fix (see fix.diff)
- In `svm_vcpu_guest_dbregs_enter`: unconditionally save the host DR7 into
  `cpudata->hstate.drs[DR7]` before clearing it (so it is available to restore
  on exit regardless of `PCB_DBREGS`).
- In `svm_vcpu_guest_dbregs_leave`: unconditionally restore that host DR7 after
  the PCB-gated restore, so a guest-armed breakpoint cannot persist.
This mirrors how the misc/FPU state is already handled.  Compile-validated
(nvmm module build); runtime not exercisable (no SVM on guest).
