diff --git a/local/patches/kernel/P4-supplementary-groups.patch b/local/patches/kernel/P4-supplementary-groups.patch index 1753aaea..1ff1e78f 100644 --- a/local/patches/kernel/P4-supplementary-groups.patch +++ b/local/patches/kernel/P4-supplementary-groups.patch @@ -1,5 +1,5 @@ diff --git a/src/context/context.rs b/src/context/context.rs -index c97c516..1c86cec 100644 +index c97c516..6d723f4 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -148,6 +148,8 @@ pub struct Context { @@ -19,8 +19,36 @@ index c97c516..1c86cec 100644 #[cfg(feature = "syscall_debug")] syscall_debug_info: crate::syscall::debug::SyscallDebugInfo::default(), +@@ -479,6 +482,7 @@ impl Context { + uid: self.euid, + gid: self.egid, + pid: self.pid, ++ groups: self.groups.clone(), + } + } + } +diff --git a/src/scheme/mod.rs b/src/scheme/mod.rs +index d30272c..9da2b28 100644 +--- a/src/scheme/mod.rs ++++ b/src/scheme/mod.rs +@@ -777,6 +777,7 @@ pub struct CallerCtx { + pub pid: usize, + pub uid: u32, + pub gid: u32, ++ pub groups: alloc::vec::Vec, + } + impl CallerCtx { + pub fn filter_uid_gid(self, euid: u32, egid: u32) -> Self { +@@ -785,6 +786,7 @@ impl CallerCtx { + pid: self.pid, + uid: euid, + gid: egid, ++ groups: self.groups, + } + } else { + self diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs -index 47588e1..30ae5ea 100644 +index 47588e1..6ffb256 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -105,6 +105,7 @@ enum ContextHandle { @@ -51,24 +79,47 @@ index 47588e1..30ae5ea 100644 HANDLES.write(token.token()).insert( id.get(), Handle { -@@ -1271,6 +1278,16 @@ impl ContextHandle { +@@ -1271,6 +1278,39 @@ impl ContextHandle { guard.prio = (info.prio as usize).min(39); Ok(size_of::()) } + Self::Groups => { ++ const NGROUPS_MAX: usize = 65536; ++ if buf.len() % size_of::() != 0 { ++ return Err(Error::new(EINVAL)); ++ } + let count = buf.len() / size_of::(); ++ if count > NGROUPS_MAX { ++ return Err(Error::new(EINVAL)); ++ } + let mut groups = Vec::with_capacity(count); + for chunk in buf.in_exact_chunks(size_of::()).take(count) { + groups.push(chunk.read_u32()?); + } -+ let mut guard = context.write(token.token()); -+ guard.groups = groups; ++ let proc_id = { ++ let guard = context.read(token.token()); ++ guard.owner_proc_id ++ }; ++ { ++ let mut guard = context.write(token.token()); ++ guard.groups = groups.clone(); ++ } ++ if let Some(pid) = proc_id { ++ let mut contexts = context::contexts(token.downgrade()); ++ let (contexts, mut t) = contexts.token_split(); ++ for context_ref in contexts.iter() { ++ let mut ctx = context_ref.write(t.token()); ++ if ctx.owner_proc_id == Some(pid) { ++ ctx.groups = groups.clone(); ++ } ++ } ++ } + Ok(count * size_of::()) + } ContextHandle::OpenViaDup => { let mut args = buf.usizes(); -@@ -1475,6 +1492,15 @@ impl ContextHandle { +@@ -1475,6 +1515,15 @@ impl ContextHandle { debug_name, }) } diff --git a/local/patches/relibc/P4-setgroups-getgroups.patch b/local/patches/relibc/P4-setgroups-getgroups.patch index 8e99f0a1..aea36ee6 100644 --- a/local/patches/relibc/P4-setgroups-getgroups.patch +++ b/local/patches/relibc/P4-setgroups-getgroups.patch @@ -39,10 +39,10 @@ index 48cce34..d9f0141 100644 ( unsafe { (*STATIC_PROC_INFO.get()).proc_fd.as_ref().unwrap() }, diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs -index f0363a3..2fc04ef 100644 +index f0363a3..db6e77d 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs -@@ -415,6 +415,31 @@ pub fn posix_getresugid() -> Resugid { +@@ -415,6 +415,54 @@ pub fn posix_getresugid() -> Resugid { sgid, } } @@ -69,13 +69,36 @@ index f0363a3..2fc04ef 100644 + +pub fn posix_getgroups() -> Vec { + let _sig_guard = tmp_disable_signals(); -+ DYNAMIC_PROC_INFO.lock().groups.clone() ++ let groups = DYNAMIC_PROC_INFO.lock().groups.clone(); ++ if !groups.is_empty() { ++ return groups; ++ } ++ drop(_sig_guard); ++ posix_readback_groups().unwrap_or_default() ++} ++ ++fn posix_readback_groups() -> Result> { ++ let auth_fd = crate::current_proc_fd().as_raw_fd(); ++ let groups_path = alloc::format!("auth-{}-groups", auth_fd); ++ let thr_fd = crate::RtTcb::current().thread_fd(); ++ let groups_fd = thr_fd.dup(groups_path.as_bytes())?; ++ ++ let mut buf = vec![0u8; 65536 * size_of::()]; ++ let n = syscall::read(groups_fd.as_raw_fd(), &mut buf)?; ++ let count = n / size_of::(); ++ let mut groups = Vec::with_capacity(count); ++ for chunk in buf[..n].chunks_exact(size_of::()) { ++ groups.push(u32::from_ne_bytes(chunk.try_into().unwrap())); ++ } ++ let mut guard = DYNAMIC_PROC_INFO.lock(); ++ guard.groups = groups.clone(); ++ Ok(groups) +} pub fn getens() -> Result { read_proc_meta(crate::current_proc_fd()).map(|meta| meta.ens as usize) } diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs -index 752339a..bff5be4 100644 +index 752339a..a0b4304 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -43,7 +43,7 @@ use crate::{ @@ -148,7 +171,7 @@ index 752339a..bff5be4 100644 } fn getpagesize() -> usize { -@@ -736,21 +702,39 @@ impl Pal for Sys { +@@ -736,21 +702,45 @@ impl Pal for Sys { } fn getrlimit(resource: c_int, mut rlim: Out) -> Result<()> { @@ -175,11 +198,17 @@ index 752339a..bff5be4 100644 - todo_skip!(0, "setrlimit({}, {:p}): not implemented", resource, rlim); - Err(Errno(EPERM)) + unsafe fn setrlimit(resource: c_int, _rlim: *const rlimit) -> Result<()> { -+ if resource as u32 == RLIMIT_NOFILE as u32 || resource as u32 == RLIMIT_NPROC as u32 { -+ Err(Errno(EPERM)) -+ } else { -+ // Other limits are silently ignored (compatibility) -+ Ok(()) ++ match resource as u32 { ++ r if r == RLIMIT_NOFILE as u32 || r == RLIMIT_NPROC as u32 => Err(Errno(EPERM)), ++ r if r == RLIMIT_CORE as u32 ++ || r == RLIMIT_STACK as u32 ++ || r == RLIMIT_DATA as u32 ++ || r == RLIMIT_AS as u32 ++ || r == RLIMIT_FSIZE as u32 => ++ { ++ Ok(()) ++ } ++ _ => Err(Errno(EINVAL)), + } } @@ -198,7 +227,7 @@ index 752339a..bff5be4 100644 Ok(()) } -@@ -913,23 +897,7 @@ impl Pal for Sys { +@@ -913,23 +903,7 @@ impl Pal for Sys { Ok(()) } @@ -223,7 +252,7 @@ index 752339a..bff5be4 100644 unsafe fn munlock(addr: *const c_void, len: usize) -> Result<()> { // Redox never swaps -@@ -953,16 +921,7 @@ impl Pal for Sys { +@@ -953,16 +927,7 @@ impl Pal for Sys { Ok(()) } @@ -241,7 +270,7 @@ index 752339a..bff5be4 100644 unsafe fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> Result<()> { let redox_rqtp = unsafe { redox_timespec::from(&*rqtp) }; -@@ -1220,9 +1179,19 @@ impl Pal for Sys { +@@ -1220,9 +1185,19 @@ impl Pal for Sys { } unsafe fn setgroups(size: size_t, list: *const gid_t) -> Result<()> {