Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ pub struct ExecutableSpec {
/// These GIDs are relative to the user namespace that is optionally set up.
pub gid: Option<gid_t>,

/// Optional supplemental GIDs to assume, in addition to any primary GID.
/// These GIDs are relative to the user namespace that is optionally set up.
pub supplemental_gids: Option<Vec<gid_t>>,

/// An optional set of process-specific resource limits.
/// If this set is not provided, setrlimit(2) will not be called.
pub process_limits: Option<ProcessResourceLimits>,
Expand Down
5 changes: 5 additions & 0 deletions src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ impl CreateRequestBuilder {
self
}

pub fn set_supplemental_gids(mut self, gids: Vec<gid_t>) -> CreateRequestBuilder {
self.config.exec.supplemental_gids = gids.into();
self
}

pub fn set_no_new_privs(mut self, no_new_privs: bool) -> CreateRequestBuilder {
self.config.exec.no_new_privs = no_new_privs;
self
Expand Down
34 changes: 31 additions & 3 deletions src/wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,11 @@ impl Wrappable for CreateRequest {
set_keep_caps()?;
// Set these *first*, before we exec. Otherwise
// we may not be able to switch after dropping caps.
apply_gid_uid(self.exec.gid, self.exec.uid)?;
apply_gid_uid(
self.exec.gid,
self.exec.uid,
self.exec.supplemental_gids.as_ref(),
)?;
// Now, we can synchronize effective/inherited/permitted caps
// as a final step.
apply_capabilities(self.capabilities.as_ref())?;
Expand Down Expand Up @@ -840,7 +844,11 @@ impl Wrappable for AttachRequest {
debug!("all namespaces joined -- forking child");
fork_and_wait()?;

apply_gid_uid(self.exec.gid, self.exec.uid)?;
apply_gid_uid(
self.exec.gid,
self.exec.uid,
self.exec.supplemental_gids.as_ref(),
)?;

self.exec.execute()
}
Expand All @@ -856,7 +864,11 @@ impl Mutatable for CreateDirMutation {
}
}

fn apply_gid_uid(gid: Option<u32>, uid: Option<u32>) -> Result<()> {
fn apply_gid_uid(
gid: Option<u32>,
uid: Option<u32>,
supplemental_gids: Option<&Vec<u32>>,
) -> Result<()> {
// NOTE - order is important here - must change GID *before* changing UID, to avoid
// locking oneself out of the GID change with an "operation not permitted" error
if let Some(target_gid) = gid {
Expand All @@ -869,6 +881,22 @@ fn apply_gid_uid(gid: Option<u32>, uid: Option<u32>) -> Result<()> {
}
}

// Set supplemental gids, if any. As with changing the primary gid, this must happen before the UID shift.
if let Some(target_supplemental_gids) = supplemental_gids {
unsafe {
let gids_libc: Vec<libc::gid_t> = target_supplemental_gids
.iter()
.map(|g| *g as libc::gid_t)
.collect();
if libc::setgroups(gids_libc.len(), gids_libc.as_ptr()) < 0 {
warn!(
"unable to set supplemental GIDs: {:?}",
Error::last_os_error()
);
}
}
}

if let Some(target_uid) = uid {
unsafe {
// Check this to avoid a spurious log if we don't need to change,
Expand Down
Loading