⬢ DragonFlyBSD Kernel Audit
DF-4588 / df4588.c
← back to finding ↓ download raw
/*
 * DF-4588 — ttm_bo_vm_fault_dfly maps TTM_PAGE_FLAG_SG pages through the
 * card node (upstream refuses: Linux ttm_bo_vm_fault, #if 0'd here at
 * ttm_bo_vm.c:161-168).  Imported (prime) BOs have ttm->pages owned by the
 * exporter; the DFly fault returns them to userspace and mutates their
 * pat_mode (pmap_page_set_memattr, ttm_bo_vm.c:695) — pages TTM does not
 * own, visible/attribute-changed for every other mapping of those pages.
 *
 * Needs amdgpu (or radeon) hardware with prime self-import:
 *   1. card0: create GEM BO (AMDGPU_GEM_CREATE)            -> handle A
 *   2. PRIME_HANDLE_TO_FD(A) -> dmabuf fd
 *   3. PRIME_FD_TO_HANDLE(fd)  -> handle B (amdgpu self-import:
 *      amdgpu_dma_buf_import creates a NEW amdgpu_bo whose ttm_tt carries
 *      TTM_PAGE_FLAG_SG, amdgpu_ttm.c:1272-1280)
 *   4. AMDGPU_GEM_MMAP(B)      -> fake offset of the SG BO
 *   5. mmap(card0, fake_off, size) + touch
 *        -> drm_mmap_single -> ttm_bo_mmap_single (drm_ttm_bdev set)
 *        -> ttm_bo_vm_fault_dfly: NO SG refusal (upstream check dead in
 *           #if 0) -> foreign SG pages entered into the importer's pmap
 *           with a TTM-chosen cache attribute.
 *
 * Hardware-gated: untested on the audit guest (no DRM device).
 */
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

struct drm_prime_handle { int32_t handle; uint32_t flags; int32_t fd; };
#define DRM_IOCTL_BASE 'd'
#define DRM_IOWR(nr, t) _IOWR(DRM_IOCTL_BASE, nr, t)
#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle)
#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle)

/* amdgpu drm ioctl base = 'D' 0x40; AMDGPU_GEM_CREATE = 0x40+B0? keep UAPI
 * minimal: the full flow needs the amdgpu-specific ioctls; see README. */
int main(void)
{
	printf("DF-4588 trigger: requires amdgpu/radeon hardware with prime "
	       "self-import (AMDGPU_GEM_CREATE -> PRIME_HANDLE_TO_FD -> "
	       "PRIME_FD_TO_HANDLE -> AMDGPU_GEM_MMAP -> mmap+touch maps the "
	       "exporter's SG pages via the card node; upstream refuses this "
	       "fault, DragonFly does not).\nThis guest has no DRM device; "
	       "not runnable here.\n");
	(void)DRM_IOCTL_PRIME_HANDLE_TO_FD; (void)DRM_IOCTL_PRIME_FD_TO_HANDLE;
	return 0;
}