init: a protocol you were not granted does not exist
The registry consults the open rows it has been parsing since P2, so reaching a contract now takes a grant as well as a binding. A caller without one is answered exactly as it would be for a name nobody ever bound: same status, same empty reply, same absent capability, byte for byte, and no log line on either path — klog_read is ungated, so a line on one and not the other would be the oracle the design set out to remove. Refusal and absence being one answer is what lets a supervisor later narrow, fake or park a child's namespace without the child learning what it was denied. The manifest gains a third permission for a shape the plan did not foresee: attestation is one hop, but the driver tree is three deep — the PS/2 keyboard and mouse are spawned by ps2-bus, which the device manager spawned — so no row could name them and PS/2 input would simply stop. lets a delegate vouch for what its children *reach*, never for what they claim; the bind path is untouched, and the laundering deputy is still refused. The review found the receive side of a rule this track had already written down. Every process holds a sendable handle to the registrar — resolve installs one for anyone who asks — and ipc_reply_wait never asked who owned the endpoint, so a stranger could dequeue there: take the provider endpoints riding bind requests, and answer other clients' opens in the registrar's name. Receiving is the owner's privilege, like binding a signal or a timer; sending remains anyone's. Suite 109/109.
This commit is contained in:
@@ -399,6 +399,22 @@ fn run() void {
|
||||
if (!process.subscribeExits(ticker)) fail("subscribing an endpoint we created to exit events was refused");
|
||||
_ = logging.write("protocol-registry: foreign timer and exit binding refused\n");
|
||||
|
||||
// 9b. Receiving is the same privilege, and it was the one member of the family
|
||||
// left unguarded. Every process holds a sendable handle to the registrar's
|
||||
// mailbox — `fs_resolve` installs one for anyone who asks — and a stranger
|
||||
// that could *dequeue* there would not merely evade the grants this fixture
|
||||
// checks: it would take the provider endpoints that ride `bind` requests
|
||||
// straight out of the queue, and answer other clients' opens in the
|
||||
// registrar's name. Sending to it stays legal; receiving on it must not be.
|
||||
// A refusal comes back as a negative errno in the length register, which
|
||||
// is the whole point: the call returns instead of parking us on someone
|
||||
// else's queue, where a success would have blocked until a request it was
|
||||
// never ours to see arrived.
|
||||
var stolen: [8]u8 = undefined;
|
||||
const theft = ipc.replyWait(registry, stolen[0..0], &stolen, null);
|
||||
if (theft.len <= ~@as(usize, 0) - 4095) fail("receiving on the registry's endpoint was allowed");
|
||||
_ = logging.write("protocol-registry: foreign receive refused\n");
|
||||
|
||||
// 10. The handle-table storm again, aimed at a **harness-run service** this
|
||||
// time. Step 4 covers PID 1, which runs its own hand-written loop; every
|
||||
// other service in the system — the VFS, the display compositor, the device
|
||||
|
||||
Reference in New Issue
Block a user