diff --git a/local/patches/kernel/P27-capability-bitmask.patch b/local/patches/kernel/P27-capability-bitmask.patch index 38b12cf4d7..e456abed16 100644 --- a/local/patches/kernel/P27-capability-bitmask.patch +++ b/local/patches/kernel/P27-capability-bitmask.patch @@ -1,122 +1,127 @@ diff --git a/src/context/context.rs b/src/context/context.rs -index 6d723f49..322cb30d 100644 +index 6d723f4..a0825ac 100644 --- a/src/context/context.rs +++ b/src/context/context.rs -@@ -149,0 +150 @@ pub struct Context { +@@ -153,0 +154,3 @@ pub struct Context { ++ /// Capability bitmask — derived from euid by procmgr: euid==0 → CAP_ALL, else 0. + pub caps: u64, -@@ -207,0 +209 @@ impl Context { -+ caps: crate::scheme::caps::CAP_ALL, -@@ -479,0 +482,3 @@ impl Context { ++ +@@ -159,0 +163,6 @@ pub struct Context { ++impl Context { + pub fn has_cap(&self, cap: u64) -> bool { -+ self.caps & cap != 0 ++ self.caps & cap == cap + } -@@ -485,0 +491 @@ impl Context { ++} ++ +@@ -485,0 +495 @@ impl Context { + caps: self.caps, diff --git a/src/scheme/acpi.rs b/src/scheme/acpi.rs -index 5d734691..1326ff57 100644 +index 5d73469..7e1558a 100644 --- a/src/scheme/acpi.rs +++ b/src/scheme/acpi.rs -@@ -15,0 +16 @@ use crate::{ -+ scheme::caps, -@@ -142 +143 @@ impl KernelScheme for AcpiScheme { +@@ -142 +142 @@ impl KernelScheme for AcpiScheme { - if ctx.uid != 0 { -+ if !ctx.has_cap(caps::CAP_ACPI) { ++ if !ctx.has_cap(crate::scheme::caps::CAP_ACPI) { diff --git a/src/scheme/caps.rs b/src/scheme/caps.rs new file mode 100644 -index 00000000..481f2369 +index 0000000..6886e88 --- /dev/null +++ b/src/scheme/caps.rs -@@ -0,0 +1,11 @@ +@@ -0,0 +1,29 @@ ++//! Kernel capability bitmask for fine-grained privilege control. ++//! ++//! Each capability is a single bit in a `u64`. Processes with `euid == 0` ++//! (via procmgr SetResugid) receive `CAP_ALL`. Non-root processes receive `0` ++//! by default. Future work: explicit capability assignment via proc scheme. ++ ++/// Register or unregister kernel schemes. +pub const CAP_SCHEME_REGISTER: u64 = 1 << 0; ++/// Map physical memory (scheme:memory/physical). +pub const CAP_PHYS_MEM: u64 = 1 << 1; ++/// Allocate IRQ vectors (scheme:irq). +pub const CAP_IRQ: u64 = 1 << 2; ++/// Access ACPI tables (scheme:acpi). +pub const CAP_ACPI: u64 = 1 << 3; ++/// Use kernel debugger (scheme:debug). +pub const CAP_SYS_DEBUG: u64 = 1 << 4; ++/// Write to arbitrary files / sys:action (scheme:sys write). +pub const CAP_SYS_WRITE: u64 = 1 << 5; ++/// Read/write model-specific registers (scheme:msr). +pub const CAP_SYS_MSR: u64 = 1 << 6; ++/// Access PS/2 keyboard/mouse (scheme:serio). +pub const CAP_SERIO: u64 = 1 << 7; ++/// Change file ownership (scheme:user chown). +pub const CAP_CHOWN: u64 = 1 << 8; ++/// Modify process attributes: setuid/setgid, ptrace, signal to arbitrary procs. +pub const CAP_PROC_ATTR: u64 = 1 << 9; ++ ++/// All capabilities set — assigned to euid == 0 processes. +pub const CAP_ALL: u64 = !0u64; diff --git a/src/scheme/debug.rs b/src/scheme/debug.rs -index 4a23b3cf..2ab347d7 100644 +index 4a23b3c..ae9a96a 100644 --- a/src/scheme/debug.rs +++ b/src/scheme/debug.rs @@ -76 +76 @@ impl KernelScheme for DebugScheme { - if ctx.uid != 0 { -+ if !ctx.has_cap(caps::CAP_SYS_DEBUG) { ++ if !ctx.has_cap(crate::scheme::caps::CAP_SYS_DEBUG) { diff --git a/src/scheme/irq.rs b/src/scheme/irq.rs -index 42229609..b1b893ac 100644 +index 4222960..bf99a85 100644 --- a/src/scheme/irq.rs +++ b/src/scheme/irq.rs -@@ -20,0 +21 @@ use super::{CallerCtx, HandleMap, OpenResult, SchemeExt, StrOrBytes}; -+use super::caps; -@@ -259 +260 @@ impl crate::scheme::KernelScheme for IrqScheme { +@@ -259 +259 @@ impl crate::scheme::KernelScheme for IrqScheme { - if ctx.uid != 0 { -+ if !ctx.has_cap(caps::CAP_IRQ) { ++ if !ctx.has_cap(crate::scheme::caps::CAP_IRQ) { diff --git a/src/scheme/memory.rs b/src/scheme/memory.rs -index c2f9f474..29754518 100644 +index c2f9f47..146c461 100644 --- a/src/scheme/memory.rs +++ b/src/scheme/memory.rs -@@ -11,0 +12 @@ use crate::{ -+ scheme::caps, -@@ -235 +236 @@ impl KernelScheme for MemoryScheme { +@@ -235 +235 @@ impl KernelScheme for MemoryScheme { - if ctx.uid != 0 -+ if !ctx.has_cap(caps::CAP_PHYS_MEM) ++ if !ctx.has_cap(crate::scheme::caps::CAP_PHYS_MEM) diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs -index 765e547f..68bb8247 100644 +index 765e547..96826de 100644 --- a/src/scheme/mod.rs +++ b/src/scheme/mod.rs -@@ -53,0 +54 @@ use self::{ +@@ -81,0 +82,2 @@ pub mod sys; +pub mod caps; -@@ -356 +357 @@ impl KernelScheme for SchemeList { ++ +@@ -356 +358 @@ impl KernelScheme for SchemeList { - if caller.uid != 0 { + if !caller.has_cap(caps::CAP_SCHEME_REGISTER) { -@@ -813,0 +815 @@ pub struct CallerCtx { +@@ -813,0 +816 @@ pub struct CallerCtx { + pub caps: u64, -@@ -815,0 +818,3 @@ impl CallerCtx { +@@ -815,0 +819,3 @@ impl CallerCtx { + pub fn has_cap(&self, cap: u64) -> bool { -+ self.caps & cap != 0 ++ self.caps & cap == cap + } -@@ -822,0 +828 @@ impl CallerCtx { +@@ -822,0 +829 @@ impl CallerCtx { + caps: self.caps, -diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs -index a9de02ea..ee033988 100644 ---- a/src/scheme/proc.rs -+++ b/src/scheme/proc.rs -@@ -1275,0 +1276 @@ impl ContextHandle { -+ guard.caps = if info.euid == 0 { crate::scheme::caps::CAP_ALL } else { 0 }; diff --git a/src/scheme/serio.rs b/src/scheme/serio.rs -index 26505021..b4ceab42 100644 +index 2650502..8e32c98 100644 --- a/src/scheme/serio.rs +++ b/src/scheme/serio.rs @@ -82 +82 @@ impl KernelScheme for SerioScheme { - if ctx.uid != 0 { -+ if !ctx.has_cap(caps::CAP_SERIO) { ++ if !ctx.has_cap(crate::scheme::caps::CAP_SERIO) { diff --git a/src/scheme/sys/mod.rs b/src/scheme/sys/mod.rs -index 9eb35644..beed2ad5 100644 +index 9eb3564..902ab5a 100644 --- a/src/scheme/sys/mod.rs +++ b/src/scheme/sys/mod.rs -@@ -26,0 +27 @@ use super::{CallerCtx, HandleMap, KernelScheme, OpenResult, StrOrBytes}; -+use super::caps; -@@ -144 +145 @@ impl KernelScheme for SysScheme { +@@ -144 +144 @@ impl KernelScheme for SysScheme { - if ctx.uid != 0 { -+ if !ctx.has_cap(caps::CAP_SYS_MSR) { -@@ -170 +171 @@ impl KernelScheme for SysScheme { ++ if !ctx.has_cap(crate::scheme::caps::CAP_SYS_MSR) { +@@ -170 +170 @@ impl KernelScheme for SysScheme { - if matches!(entry.1, Wr(_)) && ctx.uid != 0 { -+ if matches!(entry.1, Wr(_)) && !ctx.has_cap(caps::CAP_SYS_WRITE) { ++ if matches!(entry.1, Wr(_)) && !ctx.has_cap(crate::scheme::caps::CAP_SYS_WRITE) { diff --git a/src/scheme/user.rs b/src/scheme/user.rs -index dfbf66b1..48fda536 100644 +index dfbf66b..e215b8d 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs -@@ -29 +29 @@ use crate::{ -- scheme::SchemeId, -+ scheme::{caps, SchemeId}, @@ -1593 +1593 @@ impl KernelScheme for UserScheme { - if cx.euid != 0 && (uid != cx.euid || gid != cx.egid) { -+ if !cx.has_cap(caps::CAP_CHOWN) && (uid != cx.euid || gid != cx.egid) { ++ if !cx.has_cap(crate::scheme::caps::CAP_CHOWN) && (uid != cx.euid || gid != cx.egid) { diff --git a/src/startup/mod.rs b/src/startup/mod.rs -index 86aabc22..4af65a37 100644 +index 86aabc2..4af65a3 100644 --- a/src/startup/mod.rs +++ b/src/startup/mod.rs @@ -190,0 +191 @@ pub(crate) fn kmain(bootstrap: Bootstrap) -> ! {