DF-4151 / trigger_sense_dma.c
/* * DF-4151 illustrative trigger sketch (NOT runnable on the audit guest: * requires an AdvanSys ASC-1000/1200 HBA plus corrupted RISC queue state). * * Mechanism under test: adv_send_scsi_queue() (advlib.c:1709-1720) reads the * free-queue head from firmware-shared LRAM (ADVV_FREE_Q_HEAD_W) and uses it * unchecked to compute the sense DMA bus address: * * q1.sense_addr = adv->sense_physbase + (free_q_head - 1) * 32; * * The sense arena is sized max_openings (<=240) slots (advansys.c:1345,1363). * A free_q_head of 0 or > max_openings (as produced by the RISC-state * corruption vectors documented for DF-2414: stale/corrupt LRAM after * hostile-target-induced firmware malfunction) makes the adapter DMA * CHECK-CONDITION sense data below/above the arena. * * This program drives the precursor an attacker controls from the SCSI bus: * a stream of commands that complete with CHECK CONDITION so the firmware * performs constant sense-DMA activity while the queue list is churned. * Run as root on a host that actually has the adapter, against a target * whose firmware state has been desynced (per DF-2414 threat model). */ #include <fcntl.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <camlib.h> /* DragonFly: /dev/passX management */ #include <bus/cam/scsi/scsi_all.h> #include <bus/cam/scsi/scsi_message.h> int main(int argc, char **argv) { const char *dev = argc > 1 ? argv[1] : "/dev/pass1"; union ccb *ccb; int fd = open(dev, O_RDWR); if (fd < 0) { perror("open (need an AdvanSys-attached pass device)"); return 1; } for (int i = 0; i < 100000; i++) { ccb = csio_build(argc, argv, 0, NULL, 0, 5000, 1, 0); (void)ccb; /* placeholder: issue TUR/REQ-SENSE churn */ usleep(100); } close(fd); fprintf(stderr, "precursor churn complete; corruption requires the " "firmware-state precondition (see VERDICT.md)\n"); return 0; } |