⬢ DragonFlyBSD Kernel Audit
DF-4640 / timeout_uaf_path.c
← back to finding ↓ download raw
/* DF-4640 — not runnable: requires a ServeRAID adapter that answers the
 * IPS_ADAPTER_INFO_CMD / IPS_DRIVE_INFO_CMD commands later than the driver's
 * 30 s / 10 s attach-time timeouts. This file documents the exact kernel
 * path; see VERDICT.md for the full static trace and env.txt for why the
 * audit guest cannot instantiate it (QEMU has no ips device model).
 *
 * Path (all on a wedged-but-alive adapter at driver attach):
 *
 *   ips_adapter_init                ips.c:426/437
 *     -> ips_get_adapter_info       ips.c:336
 *     -> ips_send_adapter_info_cmd  ips_commands.c:288
 *          bus_dmamem_alloc(data_dmatag, &command->data_buffer, ...)  :307
 *          sc->ips_issue_cmd(command)          (issued to hardware)    :284
 *          ips_timed_wait(command, "ips", 30*hz) -> ETIMEDOUT          :317
 *          bus_dmamap_unload(...)                                     :325
 *          bus_dmamem_free(data_dmatag, data_buffer, dmamap)          :328  <-- freed
 *          bus_dma_tag_destroy(data_dmatag)                           :330
 *          ips_insert_free_cmd(sc, command)  -> STATIC_BUSY cleared   :331  <-- slot recycled
 *
 *   ...adapter finally completes at t > 30 s:
 *     a) device DMA-writes the info block into the FREED data_buffer
 *        (UAF write by hardware into kernel heap), and
 *     b) ips_morpheus_check_intr (ips.c:567-576) runs
 *            command = &sc->commandarray[0];
 *            command->callback(command);
 *        on a slot that may since have been re-gotten by
 *        ips_update_nvram/ips_get_drive_info — ips_get_free_cmd zeroes
 *        `callback` (ips.c:232), so the late interrupt can call NULL, or
 *        fire the NEW command's callback for a command never issued.
 *
 * Same shape at ips_send_drive_info_cmd :411-432 with a 10 s budget.
 * Sibling wait-family defect: the remaining static commands
 * (nvram :673, flush :471, ffdc :558, config-sync :722, error-table :743)
 * use ips_timed_wait(..., 0) = INFINITE tsleep, so a card that wedges mid-
 * attach hangs the boot thread forever instead (no timeout, no unwind).
 */
int main(void) { return 0; }