test: the attacker the device suite never had
The audit's sharpest finding was structural, not a bug: a fully green suite had hidden six real defects because it contains no attacker. Every device case asserts that a driver handed its own hardware can drive it. None asked what a process handed NOTHING can do. device-authority-test is that process. It is spawned with no device and asserts what it therefore cannot do: it cannot give away a device another task holds, nor a free one, because the kernel's rule is that you may give away what you hold and the device's state is irrelevant to a process holding nothing. Asserted across every device the machine actually has, so it cannot pass by accident of which one happened to be free at boot — six on QEMU, none of them its. A positive control runs first. device_enumerate works from this process, so the refusals below it are decisions rather than a syscall path that is simply broken here; without it, "everything failed" would read identically to "the assertions are meaningless". A nonexistent device is refused as NoSuchDevice rather than NotHeld, because a refusal that cannot name its own rule is what cost a debugging session on the Ryzen. What it deliberately does not assert, and says so in its header: device_claim is still first-come-first-served at this point in the run. That is the hole D6 closes, and the claim half of the invariant joins this fixture then. Asserting it now would be writing a test that documents the bug. Verified to discriminate: removing the holder check flips "every transfer by a non-holder is refused" while the positive control keeps passing. Suite 117 -> 118.
This commit is contained in:
@@ -263,6 +263,8 @@ pub fn run(case: []const u8, boot_information: *const BootInformation) void {
|
||||
apertureTest();
|
||||
} else if (eql(case, "device-transfer")) {
|
||||
deviceTransferTest(boot_information);
|
||||
} else if (eql(case, "device-authority")) {
|
||||
deviceAuthorityTest(boot_information);
|
||||
} else if (eql(case, "device-manager")) {
|
||||
deviceManagerTest(boot_information);
|
||||
} else if (eql(case, "protocol-registry")) {
|
||||
@@ -4219,6 +4221,49 @@ fn protocolRegistryTest(boot_information: *const BootInformation) void {
|
||||
///
|
||||
/// The fixture's `protocol-denied: ok` is the marker; each step prints its own
|
||||
/// line, which the harness's ordered regex reads.
|
||||
/// The attacker the device suite never had. The audit's finding was that a fully
|
||||
/// green suite had missed six real defects because it *contains no attacker* — every
|
||||
/// device case asserts a driver handed its hardware can drive it, and none asks what a
|
||||
/// process handed **nothing** can do.
|
||||
///
|
||||
/// The fixture is spawned with no device and asserts what it therefore cannot do. It
|
||||
/// runs without the device manager on purpose: nothing here needs a driver, and a boot
|
||||
/// with fewer moving parts makes the refusals unambiguous.
|
||||
fn deviceAuthorityTest(boot_information: *const BootInformation) void {
|
||||
log("DANOS-TEST-BEGIN: device-authority\n", .{});
|
||||
if (boot_information.initial_ramdisk_len == 0) {
|
||||
check("bootloader handed over an initial_ramdisk", false);
|
||||
result();
|
||||
return;
|
||||
}
|
||||
const image = @as([*]const u8, @ptrFromInt(boot_handoff.physicalToVirtual(boot_information.initial_ramdisk_base)))[0..boot_information.initial_ramdisk_len];
|
||||
const rd = initial_ramdisk.Reader.init(image) orelse {
|
||||
check("initial_ramdisk image is valid", false);
|
||||
result();
|
||||
return;
|
||||
};
|
||||
|
||||
process.setInitialRamdisk(image);
|
||||
check("device-authority-test spawned", spawnNamedWithArg(rd, "device-authority-test", "run"));
|
||||
|
||||
const pass_marker = "device-authority: ok";
|
||||
const fail_marker = "device-authority: FAIL";
|
||||
scheduler.setPriority(1);
|
||||
const deadline = architecture.millis() + 20000;
|
||||
var saw_pass = false;
|
||||
var saw_fail = false;
|
||||
while (architecture.millis() < deadline and !saw_pass and !saw_fail) {
|
||||
if (bufferHas(pass_marker)) saw_pass = true;
|
||||
if (bufferHas(fail_marker)) saw_fail = true;
|
||||
scheduler.yield();
|
||||
}
|
||||
scheduler.setPriority(4);
|
||||
|
||||
check("no authority assertion failed", !saw_fail);
|
||||
check("the attacker completed every assertion", saw_pass);
|
||||
result();
|
||||
}
|
||||
|
||||
fn protocolDeniedTest(boot_information: *const BootInformation) void {
|
||||
log("DANOS-TEST-BEGIN: protocol-denied\n", .{});
|
||||
if (boot_information.initial_ramdisk_len == 0) {
|
||||
|
||||
Reference in New Issue
Block a user