Phase 1. Real boards expose port connectors and expansion slots; QEMU emits none, so a guest dmidecode looks conspicuously empty. Inject a plausible desktop default set (USB/LAN/audio ports + PCIe/M.2 slots) via the existing type8/type9 build path when none were configured. Inert without a seed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Anti-detect patch series
Quilt patches injected (by make prepare) into pve-qemu/debian/patches/series,
applied in order during the .deb build. Each wires a stock QEMU literal to a
spoof_*() getter from the in-tree module (hw/misc/spoof.{c,h}, dropped in by
the Makefile). The getter returns the seed-derived value, or the stock default
when no spoof-seed is set — so the whole series is inert until a VM opts in.
Authored against the pinned pve-qemu/qemu tree (QEMU 11.0) so the context lines
match exactly. Naming: 0002 = infra, 0010+ = one aspect each.
| patch | covers |
|---|---|
| 0002-x86-machine-spoof-properties | register spoof-seed / spoof-mode / spoof-hv / spoof-waet / spoof-vmgenid / spoof-pvpanic machine props |
| 0010-acpi-table-header | ACPI OEM id / table id / creator + FADT hypervisor-vendor |
| 0011-acpi-policy-waet-vmgenid | drop the WAET table; skip the vmgenid SSDT when policy = hide |
| 0012-acpi-device-hids | vmgenid _HID (mask), pvpanic _HID (hide), fw_cfg _HID |
| 0013-cpuid-kvm-sig-freq | CPUID KVM signature + leaf 0x16 frequency |
| 0014-fwcfg-signatures | fw_cfg selector + DMA signatures |
| 0015-smbios-vm-bit | clear the SMBIOS type0 "VM" characteristic bit |
| 0016-edid-monitor | EDID vendor / name / model / serial / manufacture-date |
| 0017-storage-identity | IDE model / serial / fw / cdrom + NVMe model / serial / fw |
| 0018-pci-subsystem-id | realize-time OEM-brand of PCI subsystem ids + class-bound nvme vendor:device |
| 0019-machine-desc | machine desc string → platform board model |
| 0021-smbios-identity | SMBIOS type3 chassis / type4 socket + cpu-mfr / type11 OEM / type17 memory |
| 0022-storage-extra | IDE WWN + rotation rate; NVMe EUI-64 + NGUID |
| 0023-cpu-microcode | CPU microcode revision (IA32_UCODE_REV), vendor-positioned |
| 0024-smbios-bios-type0 | SMBIOS type0 BIOS vendor/version/date + type1 system manufacturer/product (real-OEM or Hyper-V persona) |
| 0025-smbios-ports-slots | SMBIOS type 8 (port connectors) + type 9 (expansion slots) default set |
The PCI-id problem (why 0018 is careful)
The PCI vendor:device id IS the guest driver-binding contract: NetKVM binds
1af4:1000, the ivshmem driver binds 1af4:1110, the GPU driver binds its id.
Spoofing those breaks the device (no driver matches). So 0018 rewrites the
subsystem id of all emulated devices (not used for binding; skips 0x1af4
because legacy-virtio encodes the device type there), and overrides the full
vendor:device ONLY for class-bound controllers that bind by class code rather
than id — currently qemu-nvme → a real NVMe vendor:device matched to the spoofed
model brand. virtio / ivshmem / GPU ids are NOT touched (their id is load-bearing);
they are de-fingerprinted by device choice (e1000e / SATA) and vfio x-pci-*.
Out of scope (handled by config or upstream, not these patches)
- xHCI vendor:device: also class-bound; prefer the
nec-usb-xhcidevice (real NEC id) via config over spoofing qemu-xhci. (qemu-nvme is handled by0018.) - HDA codec id (
QEMU_HDA_ID_VENDOR 0x1af4): a compile-time constant baked into astatic constcodec descriptor; spoofing needs a runtime override of the GET_PARAMETER verb response. - vmport/vmmouse (VMware backdoor port 0x5658): disable via
-machine vmport=off(a machine option). - hv-mode / hypervisor bit: via the CPU model flags (
cpu: host,hidden=1+ hv enlightenments). The module'sspoof_hv_modepolicy is the intent; enforcement is configuration.