test: block-range — the discrimination fixture for range confinement (V2a)
A process acquires a block channel the way a filesystem does (consumer-hello the device manager), confines ITSELF to blocks [1,3), then proves the clamp and the gate: volume-relative LBA 0 maps inside the range and reads; a read reaching past the range is refused; geometry reports the confined size; and a confined caller can no longer call define_range (no widening, no escape). It gates on argv so the ramdisk sweep leaves it silent in other boots, and coexists with fat (ranges are per-badge). Discrimination (verified by reverting usb-storage to pre-clamp f1bdce2~1): the unconfined read still succeeds but define_range returns ENOSYS, so the fixture cannot arm confinement and the case fails — exactly the property the clamp adds. With the clamp: block-range 1/1.
This commit is contained in:
@@ -265,6 +265,8 @@ pub fn run(case: []const u8, boot_information: *const BootInformation) void {
|
||||
deviceTransferTest(boot_information);
|
||||
} else if (eql(case, "device-authority")) {
|
||||
deviceAuthorityTest(boot_information);
|
||||
} else if (eql(case, "block-range")) {
|
||||
blockRangeTest(boot_information);
|
||||
} else if (eql(case, "device-manager")) {
|
||||
deviceManagerTest(boot_information);
|
||||
} else if (eql(case, "protocol-registry")) {
|
||||
@@ -3034,6 +3036,31 @@ fn fatMountTest(boot_information: *const BootInformation) void {
|
||||
result();
|
||||
}
|
||||
|
||||
/// Per-sender range confinement (V2a, docs/volume-manager-plan.md): boot the
|
||||
/// full tree so the USB storage chain is up, then spawn block-range-test, which
|
||||
/// acquires the block channel, confines ITSELF to a sub-range, and asserts it
|
||||
/// cannot read past that range or widen it. The fixture's markers are the
|
||||
/// assertion (the QEMU expect regex matches them); this only boots and spawns.
|
||||
fn blockRangeTest(boot_information: *const BootInformation) void {
|
||||
log("DANOS-TEST-BEGIN: block-range\n", .{});
|
||||
if (boot_information.initial_ramdisk_len == 0) {
|
||||
check("bootloader handed over the initial_ramdisk", false);
|
||||
result();
|
||||
return;
|
||||
}
|
||||
const ramdisk = @as([*]const u8, @ptrFromInt(boot_handoff.physicalToVirtual(boot_information.initial_ramdisk_base)))[0..boot_information.initial_ramdisk_len];
|
||||
const rd = initial_ramdisk.Reader.init(ramdisk) orelse {
|
||||
check("initial_ramdisk image is valid", false);
|
||||
result();
|
||||
return;
|
||||
};
|
||||
process.setInitialRamdisk(ramdisk);
|
||||
const spawned = if (process.spawnBundled("/system/services/init")) true else |_| false;
|
||||
check("init spawned (boots the USB storage chain)", spawned);
|
||||
check("block-range-test spawned", spawnNamedWithArg(rd, "block-range-test", "run"));
|
||||
result();
|
||||
}
|
||||
|
||||
fn bootServiceTreeTest(boot_information: *const BootInformation, comptime label: []const u8) void {
|
||||
log("DANOS-TEST-BEGIN: " ++ label ++ "\n", .{});
|
||||
if (boot_information.initial_ramdisk_len == 0) {
|
||||
|
||||
Reference in New Issue
Block a user