[Bug 264294] guest can trick bhyve xhci into reading through a guest-controlled pointer

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 27 May 2022 16:43:24 UTC

            Bug ID: 264294
           Summary: guest can trick bhyve xhci into reading through a
                    guest-controlled pointer
           Product: Base System
           Version: Unspecified
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: bhyve
          Assignee: virtualization@FreeBSD.org
          Reporter: rtm@lcs.mit.edu

The second union in Bhyve's struct pci_xhci_dev_ep causes these two
fields to occupy the same memory:

#define ep_ringaddr     _ep_trb_rings._epu_trb.ringaddr
#define ep_sctx_trbs    _ep_trb_rings._epu_sctx_trbs

Which of the two bhyve's pci_xhci.c uses depends on whether the guest
configures the number of streams to be non-zero. Bhyve interprets one
as a guest address that must be checked and mapped before each use,
and the other as a host address that can be used directly with no
checking. In the former case, the guest provides the value; in the
latter, Bhyve.

The number of streams is determined by bits in ep_ctx->dwEpCtx0, which
lives in guest memory. So it's possible for the guest to tell byhve's
xhci to configure an endpoint with the number of streams set to zero,
which causes pci_xhci_init_ep() to set devep->ep_ringaddr to a
guest-provided value XYZ (assumed to be an address in guest memory,
but can be anything the guest wants). Later, the guest can change
ep_ctx->dwEpCtx0 to indicate multiple streams, and write to an xhci
doorbell register, causing Byhyve's pci_xhci_device_doorbell() to

                sctx_tr = &devep->ep_sctx_trbs[streamid];
                ringaddr = sctx_tr->ringaddr;

which interprets devep->ep_sctx_trbs as a *host* pointer. But those
bits contain the guest-provided value XYZ previously written there by
pci_xhci_init_ep(). So "sctx_tr->ringaddr" will dereference a pointer
provided by the guest, without any checks.

I have a modified FreeBSD guest that makes Bhyve crash due to this

You are receiving this mail because:
You are the assignee for the bug.