mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 12:14:48 +00:00
runk: Allow runk to launch a container without pid namespace
Allow runk to launch a container even though users don't specify the pid namespace in `config.json` because general container runtimes such as runc also can launch a container without the namespace. On the other hand, Kata Containers doesn't allow it due to security issue so this feature should be enabled in only runk. Fixes: #7168 Signed-off-by: Manabu Sugimoto <Manabu.Sugimoto@sony.com>
This commit is contained in:
parent
ce8e3cc091
commit
f1d8de9be6
@ -80,6 +80,7 @@ const CLOG_FD: &str = "CLOG_FD";
|
||||
const FIFO_FD: &str = "FIFO_FD";
|
||||
const HOME_ENV_KEY: &str = "HOME";
|
||||
const PIDNS_FD: &str = "PIDNS_FD";
|
||||
const PIDNS_ENABLED: &str = "PIDNS_ENABLED";
|
||||
const CONSOLE_SOCKET_FD: &str = "CONSOLE_SOCKET_FD";
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -280,6 +281,17 @@ pub struct SyncPc {
|
||||
pid: pid_t,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PidNs {
|
||||
enabled: bool,
|
||||
fd: Option<i32>,
|
||||
}
|
||||
impl PidNs {
|
||||
pub fn new(enabled: bool, fd: Option<i32>) -> Self {
|
||||
Self { enabled, fd }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Container: BaseContainer {
|
||||
fn pause(&mut self) -> Result<()>;
|
||||
fn resume(&mut self) -> Result<()>;
|
||||
@ -339,16 +351,20 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
||||
let crfd = std::env::var(CRFD_FD)?.parse::<i32>().unwrap();
|
||||
let cfd_log = std::env::var(CLOG_FD)?.parse::<i32>().unwrap();
|
||||
|
||||
// get the pidns fd from parent, if parent had passed the pidns fd,
|
||||
// then get it and join in this pidns; otherwise, create a new pidns
|
||||
// by unshare from the parent pidns.
|
||||
match std::env::var(PIDNS_FD) {
|
||||
Ok(fd) => {
|
||||
let pidns_fd = fd.parse::<i32>().context("get parent pidns fd")?;
|
||||
sched::setns(pidns_fd, CloneFlags::CLONE_NEWPID).context("failed to join pidns")?;
|
||||
let _ = unistd::close(pidns_fd);
|
||||
if std::env::var(PIDNS_ENABLED)?.eq(format!("{}", true).as_str()) {
|
||||
// get the pidns fd from parent, if parent had passed the pidns fd,
|
||||
// then get it and join in this pidns; otherwise, create a new pidns
|
||||
// by unshare from the parent pidns.
|
||||
match std::env::var(PIDNS_FD) {
|
||||
Ok(fd) => {
|
||||
let pidns_fd = fd.parse::<i32>().context("get parent pidns fd")?;
|
||||
sched::setns(pidns_fd, CloneFlags::CLONE_NEWPID).context("failed to join pidns")?;
|
||||
let _ = unistd::close(pidns_fd);
|
||||
}
|
||||
Err(_e) => {
|
||||
sched::unshare(CloneFlags::CLONE_NEWPID)?;
|
||||
}
|
||||
}
|
||||
Err(_e) => sched::unshare(CloneFlags::CLONE_NEWPID)?,
|
||||
}
|
||||
|
||||
match unsafe { fork() } {
|
||||
@ -983,9 +999,13 @@ impl BaseContainer for LinuxContainer {
|
||||
}
|
||||
|
||||
let pidns = get_pid_namespace(&self.logger, linux)?;
|
||||
#[cfg(not(feature = "standard-oci-runtime"))]
|
||||
if !pidns.enabled {
|
||||
return Err(anyhow!("cannot find the pid ns"));
|
||||
}
|
||||
|
||||
defer!(if let Some(pid) = pidns {
|
||||
let _ = unistd::close(pid);
|
||||
defer!(if let Some(fd) = pidns.fd {
|
||||
let _ = unistd::close(fd);
|
||||
});
|
||||
|
||||
let exec_path = std::env::current_exe()?;
|
||||
@ -1008,14 +1028,15 @@ impl BaseContainer for LinuxContainer {
|
||||
.env(CRFD_FD, format!("{}", crfd))
|
||||
.env(CWFD_FD, format!("{}", cwfd))
|
||||
.env(CLOG_FD, format!("{}", cfd_log))
|
||||
.env(CONSOLE_SOCKET_FD, console_name);
|
||||
.env(CONSOLE_SOCKET_FD, console_name)
|
||||
.env(PIDNS_ENABLED, format!("{}", pidns.enabled));
|
||||
|
||||
if p.init {
|
||||
child = child.env(FIFO_FD, format!("{}", fifofd));
|
||||
}
|
||||
|
||||
if pidns.is_some() {
|
||||
child = child.env(PIDNS_FD, format!("{}", pidns.unwrap()));
|
||||
if pidns.fd.is_some() {
|
||||
child = child.env(PIDNS_FD, format!("{}", pidns.fd.unwrap()));
|
||||
}
|
||||
|
||||
child.spawn()?;
|
||||
@ -1249,11 +1270,11 @@ pub fn update_namespaces(logger: &Logger, spec: &mut Spec, init_pid: RawFd) -> R
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_pid_namespace(logger: &Logger, linux: &Linux) -> Result<Option<RawFd>> {
|
||||
fn get_pid_namespace(logger: &Logger, linux: &Linux) -> Result<PidNs> {
|
||||
for ns in &linux.namespaces {
|
||||
if ns.r#type == "pid" {
|
||||
if ns.path.is_empty() {
|
||||
return Ok(None);
|
||||
return Ok(PidNs::new(true, None));
|
||||
}
|
||||
|
||||
let fd =
|
||||
@ -1269,11 +1290,11 @@ fn get_pid_namespace(logger: &Logger, linux: &Linux) -> Result<Option<RawFd>> {
|
||||
e
|
||||
})?;
|
||||
|
||||
return Ok(Some(fd));
|
||||
return Ok(PidNs::new(true, Some(fd)));
|
||||
}
|
||||
}
|
||||
|
||||
Err(anyhow!("cannot find the pid ns"))
|
||||
Ok(PidNs::new(false, None))
|
||||
}
|
||||
|
||||
fn is_userns_enabled(linux: &Linux) -> bool {
|
||||
|
Loading…
Reference in New Issue
Block a user