feat: Phase 2 - kernel capability bitmask (uid==0 -> has_cap())
Replace all 9 kernel uid==0 privilege checks with a capability bitmask model. Adds caps:u64 field to Context and CallerCtx, with CAP_ALL for root processes. Zero behavioral change - uid==0 still gets all caps. New module: src/scheme/caps.rs with 10 capability constants. 9 check sites converted: acpi, irq, memory, debug, serio, sys (msr+write), scheme registration, and fchown. Patch: local/patches/kernel/P27-capability-bitmask.patch
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
diff --git a/src/context/context.rs b/src/context/context.rs
|
||||
index 6d723f49..322cb30d 100644
|
||||
--- a/src/context/context.rs
|
||||
+++ b/src/context/context.rs
|
||||
@@ -149,0 +150 @@ pub struct Context {
|
||||
+ pub caps: u64,
|
||||
@@ -207,0 +209 @@ impl Context {
|
||||
+ caps: crate::scheme::caps::CAP_ALL,
|
||||
@@ -479,0 +482,3 @@ impl Context {
|
||||
+ pub fn has_cap(&self, cap: u64) -> bool {
|
||||
+ self.caps & cap != 0
|
||||
+ }
|
||||
@@ -485,0 +491 @@ impl Context {
|
||||
+ caps: self.caps,
|
||||
diff --git a/src/scheme/acpi.rs b/src/scheme/acpi.rs
|
||||
index 5d734691..1326ff57 100644
|
||||
--- a/src/scheme/acpi.rs
|
||||
+++ b/src/scheme/acpi.rs
|
||||
@@ -15,0 +16 @@ use crate::{
|
||||
+ scheme::caps,
|
||||
@@ -142 +143 @@ impl KernelScheme for AcpiScheme {
|
||||
- if ctx.uid != 0 {
|
||||
+ if !ctx.has_cap(caps::CAP_ACPI) {
|
||||
diff --git a/src/scheme/caps.rs b/src/scheme/caps.rs
|
||||
new file mode 100644
|
||||
index 00000000..481f2369
|
||||
--- /dev/null
|
||||
+++ b/src/scheme/caps.rs
|
||||
@@ -0,0 +1,11 @@
|
||||
+pub const CAP_SCHEME_REGISTER: u64 = 1 << 0;
|
||||
+pub const CAP_PHYS_MEM: u64 = 1 << 1;
|
||||
+pub const CAP_IRQ: u64 = 1 << 2;
|
||||
+pub const CAP_ACPI: u64 = 1 << 3;
|
||||
+pub const CAP_SYS_DEBUG: u64 = 1 << 4;
|
||||
+pub const CAP_SYS_WRITE: u64 = 1 << 5;
|
||||
+pub const CAP_SYS_MSR: u64 = 1 << 6;
|
||||
+pub const CAP_SERIO: u64 = 1 << 7;
|
||||
+pub const CAP_CHOWN: u64 = 1 << 8;
|
||||
+pub const CAP_PROC_ATTR: u64 = 1 << 9;
|
||||
+pub const CAP_ALL: u64 = !0u64;
|
||||
diff --git a/src/scheme/debug.rs b/src/scheme/debug.rs
|
||||
index 4a23b3cf..2ab347d7 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) {
|
||||
diff --git a/src/scheme/irq.rs b/src/scheme/irq.rs
|
||||
index 42229609..b1b893ac 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 {
|
||||
- if ctx.uid != 0 {
|
||||
+ if !ctx.has_cap(caps::CAP_IRQ) {
|
||||
diff --git a/src/scheme/memory.rs b/src/scheme/memory.rs
|
||||
index c2f9f474..29754518 100644
|
||||
--- a/src/scheme/memory.rs
|
||||
+++ b/src/scheme/memory.rs
|
||||
@@ -11,0 +12 @@ use crate::{
|
||||
+ scheme::caps,
|
||||
@@ -235 +236 @@ impl KernelScheme for MemoryScheme {
|
||||
- if ctx.uid != 0
|
||||
+ if !ctx.has_cap(caps::CAP_PHYS_MEM)
|
||||
diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs
|
||||
index 765e547f..68bb8247 100644
|
||||
--- a/src/scheme/mod.rs
|
||||
+++ b/src/scheme/mod.rs
|
||||
@@ -53,0 +54 @@ use self::{
|
||||
+pub mod caps;
|
||||
@@ -356 +357 @@ impl KernelScheme for SchemeList {
|
||||
- if caller.uid != 0 {
|
||||
+ if !caller.has_cap(caps::CAP_SCHEME_REGISTER) {
|
||||
@@ -813,0 +815 @@ pub struct CallerCtx {
|
||||
+ pub caps: u64,
|
||||
@@ -815,0 +818,3 @@ impl CallerCtx {
|
||||
+ pub fn has_cap(&self, cap: u64) -> bool {
|
||||
+ self.caps & cap != 0
|
||||
+ }
|
||||
@@ -822,0 +828 @@ 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
|
||||
--- 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) {
|
||||
diff --git a/src/scheme/sys/mod.rs b/src/scheme/sys/mod.rs
|
||||
index 9eb35644..beed2ad5 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 {
|
||||
- if ctx.uid != 0 {
|
||||
+ if !ctx.has_cap(caps::CAP_SYS_MSR) {
|
||||
@@ -170 +171 @@ impl KernelScheme for SysScheme {
|
||||
- if matches!(entry.1, Wr(_)) && ctx.uid != 0 {
|
||||
+ if matches!(entry.1, Wr(_)) && !ctx.has_cap(caps::CAP_SYS_WRITE) {
|
||||
diff --git a/src/scheme/user.rs b/src/scheme/user.rs
|
||||
index dfbf66b1..48fda536 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) {
|
||||
diff --git a/src/startup/mod.rs b/src/startup/mod.rs
|
||||
index 86aabc22..4af65a37 100644
|
||||
--- a/src/startup/mod.rs
|
||||
+++ b/src/startup/mod.rs
|
||||
@@ -190,0 +191 @@ pub(crate) fn kmain(bootstrap: Bootstrap) -> ! {
|
||||
+ context.caps = crate::scheme::caps::CAP_ALL;
|
||||
Reference in New Issue
Block a user