feat(apps): permission manager equips apps (manifest+consent+decisions in /system), launches via init w/ file grant; shell unprivileged (/home); install/apps/allow/revoke; revoke stops running app; app-image tool; counter app

This commit is contained in:
2026-10-27 22:56:44 +01:00
parent 9bc31a9bbe
commit 90e11eb2e8
51 changed files with 1766 additions and 644 deletions

View File

@@ -9,6 +9,14 @@ pub enum Device {
Input,
}
/// A storage grant: a folder (or the whole disk, `b""`) and whether it may
/// be changed.
#[derive(Clone, Copy)]
pub struct Scope {
pub path: &'static [u8],
pub write: bool,
}
pub struct Program {
pub name: &'static str,
pub file: &'static [u8],
@@ -19,6 +27,8 @@ pub struct Program {
/// Earlier programs' endpoints it may call, in its next slots; each
/// program's copy carries its own badge, so a server can tell them apart.
pub uses: &'static [&'static str],
/// Storage it may reach, in the slot after `uses`.
pub storage: Option<Scope>,
/// Takes the console over from init; everyone else prints through it.
pub console: bool,
/// May have init spawn programs, whose limits together stay within this.
@@ -43,6 +53,7 @@ const fn server(name: &'static str, file: &'static [u8], limits: Limits) -> Prog
serves: true,
device: None,
uses: &[],
storage: None,
console: false,
spawns: None,
system_control: false,
@@ -62,7 +73,15 @@ pub const SERVERS: &[Program] = &[
},
// Text on the display, lines from the keyboard (it takes input focus).
Program { uses: &["display"], ..server("terminal", b"bin/terminal", SMALL) },
server("permission", b"bin/permission", SMALL),
// The only one that equips apps (docs/apps.md): it reaches every app's
// files and the owner's decisions, and runs apps through init.
Program {
uses: &["terminal", "display"],
storage: Some(Scope { path: b"", write: true }),
// Room for a few apps at a time.
spawns: Some(Limits { pages: 512, endpoints: 8, notifications: 8, regions: 8 }),
..server("permission", b"bin/permission", Limits { pages: 96, ..SMALL })
},
server("session", b"bin/session", SMALL),
];
@@ -70,18 +89,20 @@ pub const SERVERS: &[Program] = &[
/// spawns through init, then reports and halts.
pub const TESTS: &[Program] = &[Program {
serves: false,
uses: &["storage"],
// The permission manager, to run an app the way the shell does.
uses: &["permission"],
storage: Some(Scope { path: b"", write: true }),
spawns: Some(Limits { pages: 128, endpoints: 2, notifications: 2, regions: 2 }),
system_control: true,
..server("spawntest", b"bin/spawntest", SMALL)
}];
/// The desktop; the test image runs the SMP self-test instead.
pub const APPS: &[Program] = &[Program {
/// The desktop; the test image runs the SMP self-test instead. The shell
/// holds the owner's files and asks the permission manager to run apps;
/// it holds nothing to give them beyond that.
pub const DESKTOP: &[Program] = &[Program {
serves: false,
// The display only to hand on, to programs whose manifest asks for it.
uses: &["terminal", "storage", "display"],
// Room for one program at a time, the way the shell runs them.
spawns: Some(Limits { pages: 256, endpoints: 2, notifications: 2, regions: 2 }),
uses: &["terminal", "permission"],
storage: Some(Scope { path: b"home", write: true }),
..server("shell", b"bin/shell", SMALL)
}];