# DF-4402 — tws_cam_attach() error symmetry: missing return after cam_sim_alloc failure, dangling sc->sim

## What
`sys/dev/raid/tws/tws_cam.c:136-202` (`tws_cam_attach`):

1. **Missing error return (boot-time NULL deref):**
   ```c
   sc->sim = cam_sim_alloc(...);
   cam_simq_release(devq);
   if (sc->sim == NULL) {
       tws_log(sc, CAM_SIM_ALLOC);      /* logged... and falls through! */
   }
   lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
   if (xpt_bus_register(sc->sim, 0) != CAM_SUCCESS) {   /* sc->sim == NULL */
   ```
   On allocation failure the driver registers a NULL SIM. `xpt_bus_register()`
   dereferences `sim` immediately (`sys/bus/cam/cam_xpt.c:4304`
   `sim_lock_assert_owned(sim->lock)` → `sim->lock` on NULL; `:4306`
   `sim->bus_id = bus` write through NULL) → NULL-pointer kernel panic during
   attach. Reachable under memory pressure at boot/driver-load.

2. **Dangling `sc->sim` on the xpt_create_path failure path (latent
   double-free):** the `xpt_bus_register` failure path NULLs `sc->sim`
   (`:180`) but the `xpt_create_path` failure path (`:185-193`) frees the sim
   (`cam_sim_free(sc->sim)`) without NULLing it — any later `tws_cam_detach()`
   (`:211-214`, xpt_bus_deregister + cam_sim_free again) would double-free /
   UAF. Today `tws_attach`'s `attach_fail_4` (`tws.c:309-316`) happens not to
   call `tws_cam_detach`, so this half is latent — but it is exactly the
   asymmetry that turns any future caller into a double free.

3. **`tws_bus_scan` failure leaks the registered bus/SIM** (`:194-198` returns
   error without deregistration).

## Impact
(1) is a denial-of-service (kernel panic) gated on `cam_sim_alloc` failing —
memory pressure during device attach. (2)/(3) are error-path hygiene with
latent UAF potential. Low severity: attach-time, resource-pressure-gated.

## Status
Cannot be exercised on the audit guest (no 3ware HBA); (1) proven by
`xpt_bus_register`'s immediate dereference — see VERDICT.md.
