Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add id mount #2833

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions crates/libcgroups/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ cgroupsv2_devices = ["rbpf", "libbpf-sys", "errno", "libc", "nix/dir"]
[dependencies]
nix = { version = "0.28.0", features = ["signal", "user", "fs"] }
procfs = "0.16.0"
oci-spec = { version = "~0.6.4", features = ["runtime"] }
#oci-spec = { version = "~0.6.4", features = ["runtime"] }
oci-spec={git="https://github.com/lengrongfu/oci-spec-rs",branch = "feat/add_idmapped_mount",features = ["runtime"] }
fixedbitset = "0.5.7"
serde = { version = "1.0", features = ["derive"] }
rbpf = { version = "0.2.0", optional = true }
Expand All @@ -34,7 +35,8 @@ tracing = { version = "0.1.40", features = ["attributes"] }

[dev-dependencies]
anyhow = "1.0"
oci-spec = { version = "~0.6.4", features = ["proptests", "runtime"] }
#oci-spec = { version = "~0.6.4", features = ["proptests", "runtime"] }
oci-spec={git="https://github.com/lengrongfu/oci-spec-rs",branch = "feat/add_idmapped_mount",features = ["proptests", "runtime"]}
quickcheck = "1"
mockall = { version = "0.12.1", features = [] }
clap = "4.1.6"
Expand Down
6 changes: 4 additions & 2 deletions crates/libcontainer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ nix = { version = "0.28.0", features = [
"term",
"hostname",
] }
oci-spec = { version = "~0.6.4", features = ["runtime"] }
#oci-spec = { version = "~0.6.4", features = ["runtime"] }
oci-spec={git="https://github.com/lengrongfu/oci-spec-rs",branch = "feat/add_idmapped_mount",features = ["runtime"] }
once_cell = "1.19.0"
procfs = "0.16.0"
prctl = "1.0.0"
Expand All @@ -56,7 +57,8 @@ safe-path = "0.1.0"
nc = "0.8.20"

[dev-dependencies]
oci-spec = { version = "~0.6.4", features = ["proptests", "runtime"] }
#oci-spec = { version = "~0.6.4", features = ["proptests", "runtime"] }
oci-spec={git="https://github.com/lengrongfu/oci-spec-rs",branch = "feat/add_idmapped_mount",features = ["proptests", "runtime"]}
quickcheck = "1"
serial_test = "3.1.1"
tempfile = "3"
Expand Down
47 changes: 47 additions & 0 deletions crates/libcontainer/src/process/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use nix::unistd::Pid;

use crate::channel::{channel, Receiver, Sender};
use crate::process::message::Message;
use crate::rootfs::mount::{IdMountParam, IdMountSource};

#[derive(Debug, thiserror::Error)]
pub enum ChannelError {
Expand Down Expand Up @@ -57,6 +58,13 @@ impl MainSender {
Ok(())
}

// process mount place
pub fn process_mount_place(&mut self, m: IdMountParam) -> Result<(), ChannelError> {
tracing::debug!("send process mapping place request");
self.sender.send(Message::SendConfigureMount(m))?;
Ok(())
}

pub fn seccomp_notify_request(&mut self, fd: RawFd) -> Result<(), ChannelError> {
self.sender
.send_fds(Message::SeccompNotify, &[fd.as_raw_fd()])?;
Expand Down Expand Up @@ -186,6 +194,23 @@ impl MainReceiver {
}
}

pub fn wait_process_mount_place(&mut self) -> Result<IdMountParam,ChannelError> {
let msg = self
.receiver
.recv()
.map_err(|err| ChannelError::ReceiveError {
msg: "waiting for process mount place".to_string(),
source: err,
})?;
match msg {
Message::SendConfigureMount(m) => Ok(m),
msg => Err(ChannelError::UnexpectedMessage {
expected: Message::SendConfigureMount(Default::default()),
received: msg,
})
}
}

pub fn close(&self) -> Result<(), ChannelError> {
self.receiver.close()?;

Expand Down Expand Up @@ -270,6 +295,12 @@ impl InitSender {
Ok(())
}

pub fn send_mount_source(&mut self, ms: &IdMountSource) -> Result<(),ChannelError> {
tracing::debug!("send mount source request");
self.sender.send(Message::ReceiveMountFd(ms.clone()))?;
Ok(())
}

pub fn close(&self) -> Result<(), ChannelError> {
self.sender.close()?;

Expand Down Expand Up @@ -301,6 +332,22 @@ impl InitReceiver {
}
}

pub fn wait_for_mount_source(&mut self) -> Result<IdMountSource,ChannelError> {
let msg = self.receiver.recv().map_err(|err| ChannelError::ReceiveError {
msg: "waiting for get mount source".to_string(),
source: err,
})?;
match msg {
Message::ReceiveMountFd(ms) => Ok(ms),
msg => Err(
ChannelError::UnexpectedMessage {
expected: Message::ReceiveMountFd(IdMountSource { file: 0 }),
received: msg,
}
)
}
}

pub fn close(&self) -> Result<(), ChannelError> {
self.receiver.close()?;

Expand Down
7 changes: 7 additions & 0 deletions crates/libcontainer/src/process/container_init_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,20 @@ pub fn container_init_process(

let in_user_ns = utils::is_in_new_userns().map_err(InitProcessError::Io)?;
let bind_service = namespaces.get(LinuxNamespaceType::User)?.is_some() || in_user_ns;
let mut ns_path: Option<PathBuf> = None;
if let Some(user_namespace) = namespaces.get(LinuxNamespaceType::User)? {
ns_path = Some(user_namespace.path().clone().unwrap());
}
let rootfs = RootFS::new();
rootfs
.prepare_rootfs(
spec,
rootfs_path,
bind_service,
namespaces.get(LinuxNamespaceType::Cgroup)?.is_some(),
ns_path,
main_sender,
init_receiver,
)
.map_err(|err| {
tracing::error!(?err, "failed to prepare rootfs");
Expand Down
43 changes: 42 additions & 1 deletion crates/libcontainer/src/process/container_main_process.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::mem;
use std::fs::File;
use std::os::fd::{AsRawFd, RawFd};
use nix::sys::wait::{waitpid, WaitStatus};
use nix::unistd::Pid;

use crate::process::args::ContainerArgs;
use crate::process::fork::{self, CloneCb};
use crate::process::intel_rdt::setup_intel_rdt;
use crate::process::{channel, container_intermediate_process};
use crate::syscall::SyscallError;
use crate::syscall::{linux, SyscallError};
use crate::user_ns::UserNamespaceConfig;

#[derive(Debug, thiserror::Error)]
Expand Down Expand Up @@ -115,6 +118,44 @@ pub fn container_main_process(container_args: &ContainerArgs) -> Result<(Pid, bo
// The intermediate process will send the init pid once it forks the init
// process. The intermediate process should exit after this point.
let init_pid = main_receiver.wait_for_intermediate_ready()?;

loop {
let id_map = main_receiver.wait_process_mount_place().unwrap();
if id_map.end {
break;
}
let mut flags = libc::OPEN_TREE_CLONE | libc::OPEN_TREE_CLOEXEC;
let id_map_flags = id_map.flags;
if id_map_flags&libc::MS_REC == libc::MS_REC {
flags |= libc::AT_RECURSIVE as std::os::raw::c_uint;
}
let mount_file = unsafe {
libc::syscall(libc::SYS_open_tree,libc::AT_FDCWD,id_map.source,flags)
};
let mut userns_file: RawFd = -1;
if id_map.user_ns_path != "" {
let file = File::open(id_map.user_ns_path).unwrap();
userns_file = file.as_raw_fd();
} else {
// TODO we need use uid and git go get fd
}

let mat = &linux::MountAttr{
attr_set: linux::MOUNT_ATTR_IDMAP,
attr_clr: 0,
propagation: 0,
userns_fd: userns_file as u64,
};
let mut set_attr_flags = libc::AT_EMPTY_PATH;
if id_map.recursive {
set_attr_flags |= libc::AT_RECURSIVE;
}
syscall.mount_setattr(mount_file as i32, "".as_ref(), set_attr_flags as u32, mat,mem::size_of::<linux::MountAttr>(),).map_err(|err| {
tracing::error!(?err, "failed to mount_setattr");
ProcessError::SyscallOther(err)
}).unwrap();
}

let mut need_to_clean_up_intel_rdt_subdirectory = false;

if let Some(linux) = container_args.spec.linux() {
Expand Down
5 changes: 5 additions & 0 deletions crates/libcontainer/src/process/message.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::fmt;

use serde::{Deserialize, Serialize};
use crate::rootfs::mount::{IdMountParam, IdMountSource};

/// Used as a wrapper for messages to be sent between child and parent processes
#[derive(Debug, Serialize, Deserialize, Clone)]
Expand All @@ -12,6 +13,8 @@ pub enum Message {
SeccompNotify,
SeccompNotifyDone,
ExecFailed(String),
SendConfigureMount(IdMountParam),
ReceiveMountFd(IdMountSource),
}

impl fmt::Display for Message {
Expand All @@ -24,6 +27,8 @@ impl fmt::Display for Message {
Message::SeccompNotify => write!(f, "SeccompNotify"),
Message::SeccompNotifyDone => write!(f, "SeccompNotifyDone"),
Message::ExecFailed(s) => write!(f, "ExecFailed({})", s),
Message::SendConfigureMount(_) => write!(f,"SendConfigureMount"),
Message::ReceiveMountFd(_) => write!(f,"ReceiveMountFd"),
}
}
}
Loading
Loading