Skip to content

Commit

Permalink
Merge pull request #131 from YJDoc2/comment-capabilities
Browse files Browse the repository at this point in the history
Document capabilities rs and refactor its drop_privileges function
  • Loading branch information
utam0k authored Jul 12, 2021
2 parents 2a7f907 + 699df64 commit 0c40908
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
4 changes: 4 additions & 0 deletions docs/doc-draft.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,7 @@ This also provides implementation for Linux syscalls for the trait.

[oci runtime specification]: https://github.com/opencontainers/runtime-spec/blob/master/runtime.md
[runc man pages]: (https://github.com/opencontainers/runc/blob/master/man/runc.8.md)

## Capabilities

- [Simple explanation of capabilities](https://blog.container-solutions.com/linux-capabilities-in-practice)
18 changes: 8 additions & 10 deletions src/capabilities.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! Handles Management of Capabilities
use crate::command::Syscall;
use caps::*;

use anyhow::Result;
use oci_spec::{LinuxCapabilities, LinuxCapabilityType};

/// Converts a list of capability types to capabilities has set
fn to_set(caps: &[LinuxCapabilityType]) -> CapsHashSet {
let mut capabilities = CapsHashSet::new();
for c in caps {
Expand All @@ -12,29 +14,25 @@ fn to_set(caps: &[LinuxCapabilityType]) -> CapsHashSet {
capabilities
}

/// reset capabilities of process calling this to effective capabilities
/// effective capability set is set of capabilities used by kernel to perform checks
/// see https://man7.org/linux/man-pages/man7/capabilities.7.html for more information
pub fn reset_effective(syscall: &impl Syscall) -> Result<()> {
log::debug!("reset all caps");
syscall.set_capability(CapSet::Effective, &caps::all())?;
Ok(())
}

/// Drop any extra granted capabilities, and reset to defaults which are in oci specification
pub fn drop_privileges(cs: &LinuxCapabilities, syscall: &impl Syscall) -> Result<()> {
let all = caps::all();
log::debug!("dropping bounding capabilities to {:?}", cs.bounding);
for c in all.difference(&to_set(&cs.bounding)) {
match c {
Capability::CAP_PERFMON | Capability::CAP_CHECKPOINT_RESTORE | Capability::CAP_BPF => {
log::warn!("{:?} doesn't support.", c);
continue;
}
_ => caps::drop(None, CapSet::Bounding, *c)?,
}
}
syscall.set_capability(CapSet::Bounding, &to_set(&cs.bounding))?;

syscall.set_capability(CapSet::Effective, &to_set(&cs.effective))?;
syscall.set_capability(CapSet::Permitted, &to_set(&cs.permitted))?;
syscall.set_capability(CapSet::Inheritable, &to_set(&cs.inheritable))?;

// check specifically for ambient, as those might not always be available
if let Err(e) = syscall.set_capability(CapSet::Ambient, &to_set(&cs.ambient)) {
log::error!("failed to set ambient capabilities: {}", e);
}
Expand Down
28 changes: 26 additions & 2 deletions src/command/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::Arc;
use std::{any::Any, mem, path::Path, ptr};

use anyhow::{bail, Result};
use caps::{errors::CapsError, CapSet, CapsHashSet};
use caps::{errors::CapsError, CapSet, Capability, CapsHashSet};
use libc::{c_char, uid_t};
use nix::{
errno::Errno,
Expand Down Expand Up @@ -114,7 +114,31 @@ impl Syscall for LinuxSyscall {

/// Set capabilities for container process
fn set_capability(&self, cset: CapSet, value: &CapsHashSet) -> Result<(), CapsError> {
caps::set(None, cset, value)
match cset {
// caps::set cannot set capabilities in bounding set,
// so we do it differently
CapSet::Bounding => {
// get all capabilities
let all = caps::all();
// the difference will give capabilities
// which are to be unset
// for each such =, drop that capability
// after this, only those which are to be set will remain set
for c in all.difference(value) {
match c {
Capability::CAP_PERFMON
| Capability::CAP_CHECKPOINT_RESTORE
| Capability::CAP_BPF => {
log::warn!("{:?} is not supported.", c);
continue;
}
_ => caps::drop(None, CapSet::Bounding, *c)?,
}
}
Ok(())
}
_ => caps::set(None, cset, value),
}
}

/// Sets hostname for process
Expand Down

0 comments on commit 0c40908

Please sign in to comment.