mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-10-31 01:13:02 +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:
		
				
					committed by
					
						 Chethan Suresh
						Chethan Suresh
					
				
			
			
				
	
			
			
			
						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 { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user