DF-4184 / emu_notes.txt
--- emulation hook for DF-4184/DF-4185 verification (guest-local only) ---
Add to sys/dev/disk/nata/ata-queue.c in ata_atapicmd() after
"ata_queue_request(request); error = request->result;":
{
extern int df_audit_emu_fixup(u_int8_t *, caddr_t, int, int);
error = df_audit_emu_fixup(request->u.atapi.ccb, data, count, error);
}
And append to sys/dev/disk/nata/atapi-cd.c:
/*
* DF-AUDIT verification emulation (guest-local, NEVER for upstream):
* emulates a crafted ATAPI drive:
* df_audit.capfail=1 : MODE_SENSE page 0x2a (capabilities) always fails
* -> acd_get_cap leaves cap zeroed at attach
* (cur_write_speed == 0)
* df_audit.mode=1 : MODE_SENSE page 0x05 (write parameters) returns
* page_length = 0xff (DF-4184 driver)
* MODE_SELECT / CLOSE_TRACK succeed and the
* data-out contents beyond byte 65 are logged
* (what a crafted receiver would get)
*/
#include <sys/kernel.h>
static int df_emu_mode = 0;
static int df_emu_capfail = 0;
TUNABLE_INT("df_audit.mode", &df_emu_mode);
TUNABLE_INT("df_audit.capfail", &df_emu_capfail);
int
df_audit_emu_fixup(u_int8_t *ccb, caddr_t data, int count, int error)
{
if (ccb[0] == 0x5d && (ccb[2] & 0x3f) == 0x2a && df_emu_capfail)
return (EIO);
if (ccb[0] == 0x5d && (ccb[2] & 0x3f) == 0x05 && df_emu_mode) {
if (data && count >= 10) {
bzero(data, count);
data[8] = 0x05;
data[9] = 0xff;
}
kprintf("DFAUDIT: forged MODE_SENSE(0x05) page_length=0xff\n");
return (0);
}
if (ccb[0] == 0x55 && df_emu_mode) {
if (count > 65) {
int i;
kprintf("DFAUDIT: MODE_SELECT count=%d from 65-byte "
"stack param, over-read bytes:\n", count);
for (i = 65; i < count; i++) {
if ((i - 65) % 32 == 0)
kprintf("DFAUDIT: +%04x:", i - 65);
kprintf("%02x", (u_char)data[i]);
if ((i - 65) % 32 == 31)
kprintf("\n");
}
if ((count - 65) % 32)
kprintf("\n");
}
return (0);
}
if (ccb[0] == 0x53 && df_emu_mode) {
kprintf("DFAUDIT: forged CLOSE_TRACK success\n");
return (0);
}
return (error);
}
--- CORRECTION (post-run): ATAPI opcodes ---
MODE SENSE(10) is 0x5a (ATAPI_MODE_SENSE_BIG, sys/sys/nata.h:331) and
CLOSE_TRACK/SESSION is 0x5b (sys/sys/nata.h:332) - the original draft of these
notes wrongly used 0x5d/0x53. Also note the hook must inspect the CALLER's ccb
argument, not request->u.atapi.ccb: the ATA layer overwrites the latter with a
REQUEST SENSE (0x03) ccb when a command fails. The final working hook is
reflected in run.log output.