# DF-4787 — dal_gpio_service_open calls define_*_registers() before NULL-checking the created pin

## What

`sys/dev/drm/amd/display/dc/gpio/gpio_service.c:243-262` — in `dal_gpio_service_open()`,
each `create_*()` result is immediately passed to `define_ddc_registers()` /
`define_hpd_registers()` **before** the `if (!pin)` check at line 276:

```c
case GPIO_ID_DDC_DATA:
        pin = service->factory.funcs->create_ddc_data(service->ctx, id, en);
        service->factory.funcs->define_ddc_registers(pin, en);   /* pin may be NULL */
break;
```

The factory implementations dereference `pin` unconditionally:

* `dce110/hw_factory_dce110.c:114-116`  `switch (pin->id)`  → read at NULL+offsetof(id)
* `dce110/hw_factory_dce110.c:137-139`  `hpd->regs = &hpd_regs[en]` (via
  `HW_HPD_FROM_BASE(pin)` = `container_of(NULL, ...)`) → **write** to a near-NULL address
* identical code in `dce80/hw_factory_dce80.c:114-120`, `dce120/hw_factory_dce120.c:129-135`,
  `dcn10/hw_factory_dcn10.c:124-130`

`dal_hw_ddc_create()` (`hw_ddc.c:212-233`) and `dal_hw_hpd_create()` (`hw_hpd.c:137-165`)
return NULL when their `kzalloc()` fails (kernel memory pressure) — and also when `en` is
out of range, though all current callers pass VBIOS/translate-bounded enum values.

Same function, second latent instance: the shipped factory tables set
`.create_generic = .create_sync = .create_gsl = NULL` on **all four** ASIC families
(`hw_factory_dce110.c:148-151`, dce80:152-155, dce120:169-172, dcn10:164-167), and
`dal_gpio_service_open` calls those pointers with no NULL check. No code in the tree
currently opens GENERIC/SYNC/GSL pins, so that arm is latent today (covered by DF-4788).

## Impact

Deterministic NULL-pointer-dereference panic (kernel DoS) when a DDC or HPD pin allocation
fails under kernel heap exhaustion during display detection / HPD hotplug handling.
No privilege boundary is crossed; no info leak; no arbitrary write (address is fixed
near-NULL).

## Reproduce (requires AMD GPU hardware — NOT available in the audit QEMU guest)

Not runnable on the audit guest: it is a KVM/q35 virtio guest with no AMD GPU and no
driver attach (see `env.txt` — `pciconf -l` shows only Intel host bridge / virtio devices;
no amdgpu/dc module loaded). A hardware PoC would fault-inject kzalloc failure
(e.g. `failslab`-style) and trigger an HPD hotplug or DDC probe.

## Fix

`fix.diff` in this directory — move the `define_*_registers()` calls after the `!pin`
check and guard the NULL creator function pointers.

## Verdict

`untested` — code-path analysis is conclusive (certain), but no AMD display hardware
exists in the verification guest, so it cannot be exercised there.
