⬢ DragonFlyBSD Kernel Audit
DF-4184 / emu_notes.txt
← back to finding ↓ download raw
--- 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.