12 KiB
12 KiB
| 1 | # /system/configuration/protocol.csv — who may claim, and who may reach, a name |
|---|---|
| 2 | # under /protocol (docs/os-development/protocol-namespace.md). |
| 3 | # |
| 4 | # init is the registrar: it serves /protocol, and every bind AND every open is |
| 5 | # checked against this file. It is AUTHORITATIVE — a name no row grants cannot be |
| 6 | # bound or reached, and a missing file means nothing may be bound or reached at |
| 7 | # all. |
| 8 | # |
| 9 | # A refused open is answered exactly as a name nobody bound is: -ENOENT, and no |
| 10 | # capability. That is not politeness, it is the model — the namespace IS the |
| 11 | # restriction, so what a process may not open simply does not exist for it, and |
| 12 | # Which is why a missing row here shows up as a client retrying forever rather |
| 13 | # than as an error: check this file first, and `readdir /protocol` second. |
| 14 | # |
| 15 | # '#' starts a comment (whole-line or trailing); blank lines are ignored. |
| 16 | # Whitespace around a field is trimmed, so columns may be padded. Four |
| 17 | # comma-separated fields per row: |
| 18 | # |
| 19 | # binary the claimant's binary path, exactly as the kernel stamped it at |
| 20 | # spawn (argv[0]) — unforgeable, read from the process records |
| 21 | # supervisor the authorized supervising TASK, written as the binary it runs — |
| 22 | # the path init was started as for its own services, the device |
| 23 | # manager's path for the drivers it starts. The one word that is not |
| 24 | # a path is 'kernel', because a kernel task has no binary; that is |
| 25 | # what the test harness's direct spawns look like. |
| 26 | # Matched by IDENTITY, not by spelling. Name alone is not identity — |
| 27 | # spawn is ungated, so a hostile process can start a granted binary |
| 28 | # itself and inherit its grants; and it can equally start its own |
| 29 | # instance of the *supervisor's* binary and have that spawn the |
| 30 | # granted one, at which point both names read correctly (the |
| 31 | # laundering deputy). So init also asks which task the supervisor |
| 32 | # is: 'kernel' means supervisor id 0, which only the kernel can |
| 33 | # confer; init's own path means this init; any other path means a |
| 34 | # task init spawned itself or one the kernel spawned. Task ids are |
| 35 | # monotonic and never reused, so an id cannot be borrowed. |
| 36 | # permission bind (provide this contract) | open (speak to it) | |
| 37 | # supervise (stand in someone else's chain — see below) |
| 38 | # name the contract, relative to /protocol |
| 39 | # |
| 40 | # A trailing '*' on any field matches any tail — how a subtree is granted whole. |
| 41 | # |
| 42 | # 'supervise' exists because attestation is one hop deep and the driver tree is |
| 43 | # three: the device manager starts the PS/2 bus, and the bus starts the keyboard |
| 44 | # and mouse drivers. Init never met the bus, so it cannot vouch for it by |
| 45 | # acquaintance — and it must not vouch for it by name, or the laundering deputy |
| 46 | # walks straight in. A 'supervise' row is the manifest saying it: a task running |
| 47 | # this binary, under this supervisor, may be the supervising task an 'open' row |
| 48 | # names, for this contract and no other. It grants the delegate nothing itself, |
| 49 | # and it is deliberately open-only — a delegate may vouch for what its children |
| 50 | # REACH, never for what they CLAIM, so every bind refusal is untouched by it. |
| 51 | # |
| 52 | # binary supervisor permission name |
| 53 | # --- the services init spawns from init.csv --------------------------------- |
| 54 | /system/services/input, /system/services/init, bind, input |
| 55 | /system/services/device-manager, /system/services/init, bind, device-manager |
| 56 | /system/services/fat, /system/services/init, bind, vfs |
| 57 | /system/services/display, /system/services/init, bind, display |
| 58 | # The discovery service ships under one neutral name per firmware (docs/discovery.md); |
| 59 | # on x86 it is the acpi service, and what it provides is the power contract. |
| 60 | /system/services/discovery, /system/services/device-manager, bind, power |
| 61 | # --- the drivers, which the device manager spawns --------------------------- |
| 62 | /system/drivers/ps2-bus, /system/services/device-manager, bind, ps2-bus |
| 63 | /system/drivers/usb-xhci-bus, /system/services/device-manager, bind, usb-transfer |
| 64 | /system/drivers/usb-storage, /system/services/device-manager, bind, block |
| 65 | /system/drivers/virtio-gpu, /system/services/device-manager, bind, scanout |
| 66 | # --- the same providers when the kernel test harness starts them directly --- |
| 67 | # A scenario boot spawns its own providers instead of letting init do it |
| 68 | # (docs/security-track-plan.md, decision 9), so the same binaries appear with |
| 69 | # 'kernel' as the supervisor. Nothing else changes: the binary must still match. |
| 70 | /system/services/input, kernel, bind, input |
| 71 | /system/services/device-manager, kernel, bind, device-manager |
| 72 | /system/services/fat, kernel, bind, vfs |
| 73 | /system/services/display, kernel, bind, display |
| 74 | /system/services/discovery, kernel, bind, power |
| 75 | # --- test fixtures ---------------------------------------------------------- |
| 76 | # The subtree rule, dogfooded: anything installed under /test may claim anything |
| 77 | # under /protocol/test, and nothing above it — whether the harness spawned it or |
| 78 | # another fixture did. |
| 79 | /test/*, kernel, bind, test/* |
| 80 | /test/*, /test/*, bind, test/* |
| 81 | # ============================================================================ |
| 82 | # open — who may REACH each contract. One row per client per contract; a client |
| 83 | # with no row here simply finds the name absent, forever. |
| 84 | # ============================================================================ |
| 85 | # --- init's own services ---------------------------------------------------- |
| 86 | # fat reaches the block device behind the volume it mounts; the compositor |
| 87 | # reaches the scanout its driver announced, its own endpoint (the mouse-listener |
| 88 | # thread opens /protocol/display like any other client — threads share no |
| 89 | # handles), and the input stream that moves the cursor. |
| 90 | /system/services/fat, /system/services/init, open, block |
| 91 | /system/services/display, /system/services/init, open, scanout |
| 92 | /system/services/display, /system/services/init, open, display |
| 93 | /system/services/display, /system/services/init, open, input |
| 94 | /system/services/display-demo, /system/services/init, open, display |
| 95 | # --- the same two when the kernel test harness starts them directly --------- |
| 96 | /system/services/display, kernel, open, scanout |
| 97 | /system/services/display, kernel, open, display |
| 98 | /system/services/display, kernel, open, input |
| 99 | /system/services/display-demo, kernel, open, display |
| 100 | # --- the drivers, and the discovery service --------------------------------- |
| 101 | # Every driver says hello to the manager that started it — one row for the whole |
| 102 | # subtree, because that handshake is what being a driver means. The rest are per |
| 103 | # driver: the storage and HID class drivers talk to their controller, the HID |
| 104 | # drivers publish into the input stream, and the GPU driver announces its scanout |
| 105 | # to the compositor. |
| 106 | /system/drivers/*, /system/services/device-manager, open, device-manager |
| 107 | /system/services/discovery, /system/services/device-manager, open, device-manager |
| 108 | /system/drivers/usb-storage, /system/services/device-manager, open, usb-transfer |
| 109 | /system/drivers/usb-hid-keyboard, /system/services/device-manager, open, usb-transfer |
| 110 | /system/drivers/usb-hid-keyboard, /system/services/device-manager, open, input |
| 111 | /system/drivers/usb-hid-mouse, /system/services/device-manager, open, usb-transfer |
| 112 | /system/drivers/usb-hid-mouse, /system/services/device-manager, open, input |
| 113 | /system/drivers/virtio-gpu, /system/services/device-manager, open, display |
| 114 | # --- the PS/2 child drivers, one hop further down --------------------------- |
| 115 | # The keyboard and mouse drivers are started by the BUS driver, not by the |
| 116 | # device manager — the one three-deep chain in the tree. Init cannot vouch for |
| 117 | # the bus by acquaintance (it never started it), so the manifest authorizes it |
| 118 | # explicitly, and only for the two contracts its children need. |
| 119 | /system/drivers/ps2-bus, /system/services/device-manager, supervise, ps2-bus |
| 120 | /system/drivers/ps2-bus, /system/services/device-manager, supervise, input |
| 121 | /system/drivers/ps2-keyboard, /system/drivers/ps2-bus, open, ps2-bus |
| 122 | /system/drivers/ps2-keyboard, /system/drivers/ps2-bus, open, input |
| 123 | /system/drivers/ps2-mouse, /system/drivers/ps2-bus, open, ps2-bus |
| 124 | /system/drivers/ps2-mouse, /system/drivers/ps2-bus, open, input |
| 125 | # --- test fixtures ---------------------------------------------------------- |
| 126 | # The /protocol/test subtree is theirs whole, the way the bind rows give it to |
| 127 | # them. Everything ABOVE that subtree is named one fixture at a time, so a |
| 128 | # fixture reaches a system contract only where a scenario needs it — which is |
| 129 | # what leaves the rest genuinely absent for the rest of them (the protocol-denied |
| 130 | # case asks for one it was not given, and is told there is no such thing). |
| 131 | /test/*, kernel, open, test/* |
| 132 | /test/*, /test/*, open, test/* |
| 133 | /test/*, kernel, open, device-manager |
| 134 | /test/*, /system/services/device-manager, open, device-manager |
| 135 | /test/system/services/input-source, kernel, open, input |
| 136 | /test/system/services/input-test, kernel, open, input |
| 137 | # The guessable-id probe (test/system/services/badge-scope-test) runs as two |
| 138 | # processes of one binary: the owner, which the scenario spawns, and the intruder, |
| 139 | # which the owner spawns with the ids it holds. Both reach the compositor — the |
| 140 | # owner to create the layer, the intruder to be refused it — so the binary is |
| 141 | # named twice, once per supervisor. The second row needs no 'supervise' |
| 142 | # delegation: the owner was spawned by the KERNEL, which is a chain init can |
| 143 | # vouch for on its own. |
| 144 | /test/system/services/badge-scope-test, kernel, open, display |
| 145 | /test/system/services/badge-scope-test, /test/*, open, display |
| 146 | # The conformance probe (test/system/services/protocol-conformance-test) asks |
| 147 | # every provider its boot bound for the envelope's reserved verbs. It reaches |
| 148 | # ONLY the two contracts its own scenario boots a provider for, named one at a |
| 149 | # time exactly like the two rows above — no subtree, no wildcard. Everything else |
| 150 | # under /protocol stays absent for it, which is the point: the fixture walks the |
| 151 | # namespace listing and reports what it could not open rather than being handed |
| 152 | # the tree to make the test look broad. |
| 153 | /test/system/services/protocol-conformance-test, kernel, open, input |
| 154 | /test/system/services/protocol-conformance-test, kernel, open, display |
| 155 | # The laundering-deputy probe (test/system/services/protocol-registry-test) runs |
| 156 | # a grandchild whose supervisor is a fixture nobody authorized — that is the |
| 157 | # point of it, and its bind must stay refused. It still has to report the verdict |
| 158 | # it got, so its reporting channel, and nothing else, is delegated. |
| 159 | /test/*, /test/*, supervise, test/verdict |