# DF-4287 — acpi_thinkpad attach: kfreeenv(NULL) panics when exactly one SMBIOS env var is absent

## What

`acpi_thinkpad_attach()` [sys/dev/acpica/acpi_thinkpad/acpi_thinkpad.c:607-624]:

```c
maker = kgetenv("smbios.system.maker");
product = kgetenv("smbios.system.product");
if (maker == NULL || product == NULL)
        goto nosmbios;
...
nosmbios:
	kfreeenv(maker);          /* acpi_thinkpad.c:623 */
	kfreeenv(product);        /* acpi_thinkpad.c:624 */
```

When **exactly one** of the two kenv variables is unset, the other
pointer is NULL and is passed to `kfreeenv()`, which forwards directly to
`kfree()` [sys/kern/kern_environment.c:332-336 — no NULL guard].
DragonFly's `_kfree()` panics on NULL:
sys/kern/kern_slaballoc.c:1404-1406 — `if (ptr == NULL) panic("trying to
free NULL pointer")`. (Note `kenv_isdynamic` is 1 on any loader-booted
system, so the kfreeenv→kfree path is live.)

Result: boot-time / driver-attach kernel panic on a ThinkPad whose
firmware provides the IBM0068/LEN0068/LEN0268 ACPI device but a missing or
malformed SMBIOS system-maker/product string (smbios(4) sets these only
when an SMBIOS table with the corresponding structure exists).

## Trigger

Hardware-gated boot path (ThinkPad + broken/partial SMBIOS table); no
user interaction. Not reproducible on the audit guest (not a ThinkPad).

## Fix

`fix.diff` — NULL-guard both kfreeenv calls. (A kernel-wide alternative —
making kfreeenv NULL-tolerant like FreeBSD's kfree(NULL) no-op — is noted
in the verdict but the minimal driver-local fix suffices.)
