mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 20:24:31 +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 FIFO_FD: &str = "FIFO_FD";
|
||||||
const HOME_ENV_KEY: &str = "HOME";
|
const HOME_ENV_KEY: &str = "HOME";
|
||||||
const PIDNS_FD: &str = "PIDNS_FD";
|
const PIDNS_FD: &str = "PIDNS_FD";
|
||||||
|
const PIDNS_ENABLED: &str = "PIDNS_ENABLED";
|
||||||
const CONSOLE_SOCKET_FD: &str = "CONSOLE_SOCKET_FD";
|
const CONSOLE_SOCKET_FD: &str = "CONSOLE_SOCKET_FD";
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -280,6 +281,17 @@ pub struct SyncPc {
|
|||||||
pid: pid_t,
|
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 {
|
pub trait Container: BaseContainer {
|
||||||
fn pause(&mut self) -> Result<()>;
|
fn pause(&mut self) -> Result<()>;
|
||||||
fn resume(&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 crfd = std::env::var(CRFD_FD)?.parse::<i32>().unwrap();
|
||||||
let cfd_log = std::env::var(CLOG_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,
|
if std::env::var(PIDNS_ENABLED)?.eq(format!("{}", true).as_str()) {
|
||||||
// then get it and join in this pidns; otherwise, create a new pidns
|
// get the pidns fd from parent, if parent had passed the pidns fd,
|
||||||
// by unshare from the parent pidns.
|
// then get it and join in this pidns; otherwise, create a new pidns
|
||||||
match std::env::var(PIDNS_FD) {
|
// by unshare from the parent pidns.
|
||||||
Ok(fd) => {
|
match std::env::var(PIDNS_FD) {
|
||||||
let pidns_fd = fd.parse::<i32>().context("get parent pidns fd")?;
|
Ok(fd) => {
|
||||||
sched::setns(pidns_fd, CloneFlags::CLONE_NEWPID).context("failed to join pidns")?;
|
let pidns_fd = fd.parse::<i32>().context("get parent pidns fd")?;
|
||||||
let _ = unistd::close(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() } {
|
match unsafe { fork() } {
|
||||||
@ -983,9 +999,13 @@ impl BaseContainer for LinuxContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pidns = get_pid_namespace(&self.logger, linux)?;
|
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 {
|
defer!(if let Some(fd) = pidns.fd {
|
||||||
let _ = unistd::close(pid);
|
let _ = unistd::close(fd);
|
||||||
});
|
});
|
||||||
|
|
||||||
let exec_path = std::env::current_exe()?;
|
let exec_path = std::env::current_exe()?;
|
||||||
@ -1008,14 +1028,15 @@ impl BaseContainer for LinuxContainer {
|
|||||||
.env(CRFD_FD, format!("{}", crfd))
|
.env(CRFD_FD, format!("{}", crfd))
|
||||||
.env(CWFD_FD, format!("{}", cwfd))
|
.env(CWFD_FD, format!("{}", cwfd))
|
||||||
.env(CLOG_FD, format!("{}", cfd_log))
|
.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 {
|
if p.init {
|
||||||
child = child.env(FIFO_FD, format!("{}", fifofd));
|
child = child.env(FIFO_FD, format!("{}", fifofd));
|
||||||
}
|
}
|
||||||
|
|
||||||
if pidns.is_some() {
|
if pidns.fd.is_some() {
|
||||||
child = child.env(PIDNS_FD, format!("{}", pidns.unwrap()));
|
child = child.env(PIDNS_FD, format!("{}", pidns.fd.unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
child.spawn()?;
|
child.spawn()?;
|
||||||
@ -1249,11 +1270,11 @@ pub fn update_namespaces(logger: &Logger, spec: &mut Spec, init_pid: RawFd) -> R
|
|||||||
Ok(())
|
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 {
|
for ns in &linux.namespaces {
|
||||||
if ns.r#type == "pid" {
|
if ns.r#type == "pid" {
|
||||||
if ns.path.is_empty() {
|
if ns.path.is_empty() {
|
||||||
return Ok(None);
|
return Ok(PidNs::new(true, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
let fd =
|
let fd =
|
||||||
@ -1269,11 +1290,11 @@ fn get_pid_namespace(logger: &Logger, linux: &Linux) -> Result<Option<RawFd>> {
|
|||||||
e
|
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 {
|
fn is_userns_enabled(linux: &Linux) -> bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user