feat(storage): scoped grants (subtree, ro/rw), narrow-only, release revokes all holders; IPC KEEP_DELEGATE opt-in; shell cd/pwd, programs get ro cwd
This commit is contained in:
26
docs/ipc.md
26
docs/ipc.md
@@ -95,6 +95,17 @@ A program's `uses` endpoints arrive as badged copies with `Execute` and
|
||||
calling, and `Delegate` lets the client send capabilities with its calls
|
||||
and hand its access to programs it starts.
|
||||
|
||||
Storage is the exception: it mints every badged copy of its own endpoint,
|
||||
and each badge names a *scope*, a subtree (or one file) and whether it may
|
||||
write. For `uses: ["storage"]` init asks it for the whole disk, read-write.
|
||||
Any holder can ask for a narrower one (`GRANT(path, write)`: inside its own
|
||||
scope, writable only if it is) and gets it with `Delegate` kept, so it can
|
||||
pass it on. Paths resolve inside the scope; `..` is refused. `RELEASE`,
|
||||
called through a grant, takes it and everything granted from it back from
|
||||
every holder (storage revokes its own copy, so the kernel deletes the
|
||||
rest), closes their files and unmaps their buffers. Badge 0 (init) is the
|
||||
whole disk; a badge storage did not issue, or took back, is `DENIED`.
|
||||
|
||||
Input reaches apps through the display server, the input server's only
|
||||
client. It subscribes to the input server with a notification, drains it
|
||||
when signalled, and passes events on to the app in focus: the last one to
|
||||
@@ -107,10 +118,10 @@ is whatever text endpoint a program was given. `READ` (`types::terminal`)
|
||||
blocks until a line is typed and returns it in chunks, the last ending in
|
||||
`\n`. The desktop is the shell, given the terminal, storage and a spawn
|
||||
allowance. A command that is not a built-in runs `name.elf`: the shell
|
||||
spawns it, gives it call-only copies of the terminal (as its log, so its
|
||||
output) and of storage, writes its arguments page, starts it and waits for
|
||||
its death. The programs share the shell's storage badge; storage hands a
|
||||
client that attaches again the same buffer, so they run one at a time.
|
||||
spawns it, gives it a call-only copy of the terminal (as its log, so its
|
||||
output) and a read-only storage grant to the shell's current directory
|
||||
(`cd`, `pwd`), writes its arguments page, starts it, waits for its death
|
||||
and releases the grant.
|
||||
|
||||
Only init holds `ProcessCreate`. Everyone else runs programs through init's
|
||||
spawn service (`types::spawn`, client `libkos::spawn`), which init serves
|
||||
@@ -159,8 +170,11 @@ A message is 4 words and at most one capability. The capability is
|
||||
transferred only if the sender's endpoint capability has `Delegate` and the
|
||||
transferred capability itself has `Delegate`; it is **copied** (the sender
|
||||
keeps its own) with the same badge and permissions minus `Delegate`: the
|
||||
receiver can use it but not pass it on. To let a process pass a capability
|
||||
on, give it with the `Delegate` syscall and explicit rights. If the receiver's
|
||||
receiver can use it but not pass it on. A sender that means the receiver
|
||||
to pass it on sets `KEEP_DELEGATE` in the capability register
|
||||
(`syscall_abi::Give`): the copy then keeps exactly the sender's rights,
|
||||
`Delegate` included. Or it gives the capability with the `Delegate` syscall
|
||||
and explicit rights. If the receiver's
|
||||
table is full, or the capability is no longer valid at delivery time, the
|
||||
message is delivered without it.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user