diff --git a/crates/libcontainer/src/rootfs/utils.rs b/crates/libcontainer/src/rootfs/utils.rs index a30c0a917..5e22430e3 100644 --- a/crates/libcontainer/src/rootfs/utils.rs +++ b/crates/libcontainer/src/rootfs/utils.rs @@ -6,7 +6,7 @@ use nix::sys::stat::SFlag; use oci_spec::runtime::{LinuxDevice, LinuxDeviceBuilder, LinuxDeviceType, Mount}; use super::mount::MountError; -use crate::syscall::linux::{self, MountRecursive}; +use crate::syscall::linux::{self, MountOption, MountRecursive}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct MountOptionConfig { @@ -131,51 +131,53 @@ pub fn parse_mount(m: &Mount) -> std::result::Result Some((false, MsFlags::empty())), - "ro" => Some((false, MsFlags::MS_RDONLY)), - "rw" => Some((true, MsFlags::MS_RDONLY)), - "suid" => Some((true, MsFlags::MS_NOSUID)), - "nosuid" => Some((false, MsFlags::MS_NOSUID)), - "dev" => Some((true, MsFlags::MS_NODEV)), - "nodev" => Some((false, MsFlags::MS_NODEV)), - "exec" => Some((true, MsFlags::MS_NOEXEC)), - "noexec" => Some((false, MsFlags::MS_NOEXEC)), - "sync" => Some((false, MsFlags::MS_SYNCHRONOUS)), - "async" => Some((true, MsFlags::MS_SYNCHRONOUS)), - "dirsync" => Some((false, MsFlags::MS_DIRSYNC)), - "remount" => Some((false, MsFlags::MS_REMOUNT)), - "mand" => Some((false, MsFlags::MS_MANDLOCK)), - "nomand" => Some((true, MsFlags::MS_MANDLOCK)), - "atime" => Some((true, MsFlags::MS_NOATIME)), - "noatime" => Some((false, MsFlags::MS_NOATIME)), - "diratime" => Some((true, MsFlags::MS_NODIRATIME)), - "nodiratime" => Some((false, MsFlags::MS_NODIRATIME)), - "bind" => Some((false, MsFlags::MS_BIND)), - "rbind" => Some((false, MsFlags::MS_BIND | MsFlags::MS_REC)), - "unbindable" => Some((false, MsFlags::MS_UNBINDABLE)), - "runbindable" => Some((false, MsFlags::MS_UNBINDABLE | MsFlags::MS_REC)), - "private" => Some((true, MsFlags::MS_PRIVATE)), - "rprivate" => Some((true, MsFlags::MS_PRIVATE | MsFlags::MS_REC)), - "shared" => Some((true, MsFlags::MS_SHARED)), - "rshared" => Some((true, MsFlags::MS_SHARED | MsFlags::MS_REC)), - "slave" => Some((true, MsFlags::MS_SLAVE)), - "rslave" => Some((true, MsFlags::MS_SLAVE | MsFlags::MS_REC)), - "relatime" => Some((true, MsFlags::MS_RELATIME)), - "norelatime" => Some((true, MsFlags::MS_RELATIME)), - "strictatime" => Some((true, MsFlags::MS_STRICTATIME)), - "nostrictatime" => Some((true, MsFlags::MS_STRICTATIME)), - unknown => { + if let Some((is_clear, flag)) = match MountOption::from_str(option.as_ref()) { + Ok(v) => match v { + MountOption::Defaults(is_clear, flag) => Some((is_clear, flag)), + MountOption::Ro(is_clear, flag) => Some((is_clear, flag)), + MountOption::Rw(is_clear, flag) => Some((is_clear, flag)), + MountOption::Suid(is_clear, flag) => Some((is_clear, flag)), + MountOption::Nosuid(is_clear, flag) => Some((is_clear, flag)), + MountOption::Dev(is_clear, flag) => Some((is_clear, flag)), + MountOption::Nodev(is_clear, flag) => Some((is_clear, flag)), + MountOption::Exec(is_clear, flag) => Some((is_clear, flag)), + MountOption::Noexec(is_clear, flag) => Some((is_clear, flag)), + MountOption::Sync(is_clear, flag) => Some((is_clear, flag)), + MountOption::Async(is_clear, flag) => Some((is_clear, flag)), + MountOption::Dirsync(is_clear, flag) => Some((is_clear, flag)), + MountOption::Remount(is_clear, flag) => Some((is_clear, flag)), + MountOption::Mand(is_clear, flag) => Some((is_clear, flag)), + MountOption::Nomand(is_clear, flag) => Some((is_clear, flag)), + MountOption::Atime(is_clear, flag) => Some((is_clear, flag)), + MountOption::Noatime(is_clear, flag) => Some((is_clear, flag)), + MountOption::Diratime(is_clear, flag) => Some((is_clear, flag)), + MountOption::Nodiratime(is_clear, flag) => Some((is_clear, flag)), + MountOption::Bind(is_clear, flag) => Some((is_clear, flag)), + MountOption::Rbind(is_clear, flag) => Some((is_clear, flag)), + MountOption::Unbindable(is_clear, flag) => Some((is_clear, flag)), + MountOption::Runbindable(is_clear, flag) => Some((is_clear, flag)), + MountOption::Private(is_clear, flag) => Some((is_clear, flag)), + MountOption::Rprivate(is_clear, flag) => Some((is_clear, flag)), + MountOption::Shared(is_clear, flag) => Some((is_clear, flag)), + MountOption::Rshared(is_clear, flag) => Some((is_clear, flag)), + MountOption::Slave(is_clear, flag) => Some((is_clear, flag)), + MountOption::Rslave(is_clear, flag) => Some((is_clear, flag)), + MountOption::Relatime(is_clear, flag) => Some((is_clear, flag)), + MountOption::Norelatime(is_clear, flag) => Some((is_clear, flag)), + MountOption::Strictatime(is_clear, flag) => Some((is_clear, flag)), + MountOption::Nostrictatime(is_clear, flag) => Some((is_clear, flag)), + }, + Err(unknown) => { if unknown == "idmap" || unknown == "ridmap" { - return Err(MountError::UnsupportedMountOption(unknown.to_string())); + return Err(MountError::UnsupportedMountOption(unknown)); } None } } { if is_clear { - flags &= !flag; + flags.remove(flag); } else { - flags |= flag; + flags.insert(flag); } continue; } diff --git a/crates/libcontainer/src/syscall/linux.rs b/crates/libcontainer/src/syscall/linux.rs index 9bc2f13de..da1e14196 100644 --- a/crates/libcontainer/src/syscall/linux.rs +++ b/crates/libcontainer/src/syscall/linux.rs @@ -38,6 +38,101 @@ const MOUNT_ATTR_STRICTATIME: u64 = 0x00000020; const MOUNT_ATTR_NODIRATIME: u64 = 0x00000080; const MOUNT_ATTR_NOSYMFOLLOW: u64 = 0x00200000; +/// Constants used by mount(2). +pub enum MountOption { + Defaults(bool, MsFlags), + Ro(bool, MsFlags), + Rw(bool, MsFlags), + Suid(bool, MsFlags), + Nosuid(bool, MsFlags), + Dev(bool, MsFlags), + Nodev(bool, MsFlags), + Exec(bool, MsFlags), + Noexec(bool, MsFlags), + Sync(bool, MsFlags), + Async(bool, MsFlags), + Dirsync(bool, MsFlags), + Remount(bool, MsFlags), + Mand(bool, MsFlags), + Nomand(bool, MsFlags), + Atime(bool, MsFlags), + Noatime(bool, MsFlags), + Diratime(bool, MsFlags), + Nodiratime(bool, MsFlags), + Bind(bool, MsFlags), + Rbind(bool, MsFlags), + Unbindable(bool, MsFlags), + Runbindable(bool, MsFlags), + Private(bool, MsFlags), + Rprivate(bool, MsFlags), + Shared(bool, MsFlags), + Rshared(bool, MsFlags), + Slave(bool, MsFlags), + Rslave(bool, MsFlags), + Relatime(bool, MsFlags), + Norelatime(bool, MsFlags), + Strictatime(bool, MsFlags), + Nostrictatime(bool, MsFlags), +} + +impl FromStr for MountOption { + type Err = String; + + fn from_str(option: &str) -> std::result::Result { + match option { + "defaults" => Ok(MountOption::Defaults(false, MsFlags::empty())), + "ro" => Ok(MountOption::Ro(false, MsFlags::MS_RDONLY)), + "rw" => Ok(MountOption::Rw(true, MsFlags::MS_RDONLY)), + "suid" => Ok(MountOption::Suid(true, MsFlags::MS_NOSUID)), + "nosuid" => Ok(MountOption::Nosuid(false, MsFlags::MS_NOSUID)), + "dev" => Ok(MountOption::Dev(true, MsFlags::MS_NODEV)), + "nodev" => Ok(MountOption::Nodev(false, MsFlags::MS_NODEV)), + "exec" => Ok(MountOption::Exec(true, MsFlags::MS_NOEXEC)), + "noexec" => Ok(MountOption::Noexec(false, MsFlags::MS_NOEXEC)), + "sync" => Ok(MountOption::Sync(false, MsFlags::MS_SYNCHRONOUS)), + "async" => Ok(MountOption::Async(true, MsFlags::MS_SYNCHRONOUS)), + "dirsync" => Ok(MountOption::Dirsync(false, MsFlags::MS_DIRSYNC)), + "remount" => Ok(MountOption::Remount(false, MsFlags::MS_REMOUNT)), + "mand" => Ok(MountOption::Mand(false, MsFlags::MS_MANDLOCK)), + "nomand" => Ok(MountOption::Nomand(true, MsFlags::MS_MANDLOCK)), + "atime" => Ok(MountOption::Atime(true, MsFlags::MS_NOATIME)), + "noatime" => Ok(MountOption::Noatime(false, MsFlags::MS_NOATIME)), + "diratime" => Ok(MountOption::Diratime(true, MsFlags::MS_NODIRATIME)), + "nodiratime" => Ok(MountOption::Nodiratime(false, MsFlags::MS_NODIRATIME)), + "bind" => Ok(MountOption::Bind(false, MsFlags::MS_BIND)), + "rbind" => Ok(MountOption::Rbind( + false, + MsFlags::MS_BIND | MsFlags::MS_REC, + )), + "unbindable" => Ok(MountOption::Unbindable(false, MsFlags::MS_UNBINDABLE)), + "runbindable" => Ok(MountOption::Runbindable( + false, + MsFlags::MS_UNBINDABLE | MsFlags::MS_REC, + )), + "private" => Ok(MountOption::Private(true, MsFlags::MS_PRIVATE)), + "rprivate" => Ok(MountOption::Rprivate( + true, + MsFlags::MS_PRIVATE | MsFlags::MS_REC, + )), + "shared" => Ok(MountOption::Shared(true, MsFlags::MS_SHARED)), + "rshared" => Ok(MountOption::Rshared( + true, + MsFlags::MS_SHARED | MsFlags::MS_REC, + )), + "slave" => Ok(MountOption::Slave(true, MsFlags::MS_SLAVE)), + "rslave" => Ok(MountOption::Rslave( + true, + MsFlags::MS_SLAVE | MsFlags::MS_REC, + )), + "relatime" => Ok(MountOption::Relatime(false, MsFlags::MS_RELATIME)), + "norelatime" => Ok(MountOption::Norelatime(true, MsFlags::MS_RELATIME)), + "strictatime" => Ok(MountOption::Strictatime(false, MsFlags::MS_STRICTATIME)), + "nostrictatime" => Ok(MountOption::Nostrictatime(true, MsFlags::MS_STRICTATIME)), + _ => Err(option.to_string()), + } + } +} + /// Constants used by mount_setattr(2). pub enum MountRecursive { /// Mount read-only.