Support setns via nsfs
This commit is contained in:
parent
9c023db7b5
commit
9fdb63800b
|
|
@ -502,6 +502,10 @@ impl FileIo for EvdevFile {
|
|||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EvdevFile {
|
||||
|
|
|
|||
|
|
@ -517,6 +517,10 @@ impl FileIo for FbHandle {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn init_in_first_kthread() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use alloc::vec;
|
||||
use core::any::Any;
|
||||
|
||||
use ostd::mm::{FallibleVmWrite, VmReader, VmWriter};
|
||||
|
||||
|
|
@ -150,4 +151,8 @@ impl FileIo for MemFile {
|
|||
fn is_offset_aware(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,6 +170,10 @@ impl FileIo for TdxGuestFile {
|
|||
_ => return_errno_with_message!(Errno::ENOTTY, "the ioctl command is unknown"),
|
||||
})
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tdx_get_quote(inblob: &[u8]) -> Result<Box<[u8]>> {
|
||||
|
|
|
|||
|
|
@ -91,4 +91,8 @@ impl FileIo for PtySlaveFile {
|
|||
fn is_offset_aware(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,6 +252,10 @@ impl FileIo for PtyMaster {
|
|||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PtyMaster {
|
||||
|
|
|
|||
|
|
@ -151,6 +151,10 @@ impl FileIo for OpenBlockFile {
|
|||
),
|
||||
})
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn lookup(id: DeviceId) -> Option<Arc<dyn Device>> {
|
||||
|
|
|
|||
|
|
@ -185,6 +185,10 @@ impl<D: TtyDriver> FileIo for TtyFile<D> {
|
|||
fn is_offset_aware(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
static TTY1: Once<Arc<Tty<VtDriver>>> = Once::new();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use crate::{
|
|||
file_table::FdFlags,
|
||||
path::Path,
|
||||
pipe::PipeHandle,
|
||||
pseudofs::{NsCommonOps, NsFile},
|
||||
utils::{
|
||||
AccessMode, AtomicStatusFlags, CreationFlags, DirentVisitor, FallocMode, FileRange,
|
||||
FlockItem, InodeType, OFFSET_MAX, RangeLockItem, RangeLockType, SeekFrom, StatusFlags,
|
||||
|
|
@ -215,6 +216,11 @@ impl InodeHandle {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn as_ns_file<T: NsCommonOps>(&self) -> Option<&NsFile<T>> {
|
||||
let file_io = self.file_io.as_ref()?;
|
||||
file_io.as_any().downcast_ref::<NsFile<T>>()
|
||||
}
|
||||
}
|
||||
|
||||
impl Pollable for InodeHandle {
|
||||
|
|
@ -519,6 +525,8 @@ pub trait FileIo: Pollable + InodeIo + Any + Send + Sync + 'static {
|
|||
fn ioctl(&self, _raw_ioctl: RawIoctl) -> Result<i32> {
|
||||
return_errno_with_message!(Errno::ENOTTY, "ioctl is not supported");
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
fn do_seek_util(offset: &Mutex<usize>, pos: SeekFrom, end: Option<usize>) -> Result<usize> {
|
||||
|
|
|
|||
|
|
@ -136,6 +136,10 @@ impl FileIo for PipeHandle {
|
|||
fn is_offset_aware(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A pipe (FIFO) that provides inter-process communication.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@
|
|||
//! 2. A `PidFile` opened by `pidfd_open` or by opening `/proc/[pid]` directory.
|
||||
|
||||
use crate::{
|
||||
fs::{file_table::FileDesc, path::MountNamespace},
|
||||
fs::{
|
||||
file_handle::FileLike, file_table::FileDesc, inode_handle::InodeHandle,
|
||||
path::MountNamespace, pseudofs::NsCommonOps,
|
||||
},
|
||||
net::uts_ns::UtsNamespace,
|
||||
prelude::*,
|
||||
process::{
|
||||
|
|
@ -34,13 +37,8 @@ pub fn sys_setns(fd: FileDesc, flags: u32, ctx: &Context) -> Result<SyscallRetur
|
|||
|
||||
let new_ns_proxy = if let Some(pid_file) = file.downcast_ref::<PidFile>() {
|
||||
build_proxy_from_pid_file(pid_file, ns_type_flags, ctx)?
|
||||
}
|
||||
// TODO: Support setting namespaces from `/proc/[pid]/ns`.
|
||||
else {
|
||||
return_errno_with_message!(
|
||||
Errno::EINVAL,
|
||||
"the FD does not refer to a supported namespace file"
|
||||
);
|
||||
} else {
|
||||
build_proxy_from_ns_file(file.as_ref(), ns_type_flags, ctx)?
|
||||
};
|
||||
|
||||
// Install the newly created `NsProxy`.
|
||||
|
|
@ -105,6 +103,56 @@ fn build_proxy_from_pid_file(
|
|||
Ok(builder.build())
|
||||
}
|
||||
|
||||
fn build_proxy_from_ns_file(
|
||||
file: &dyn FileLike,
|
||||
flags: CloneFlags,
|
||||
ctx: &Context,
|
||||
) -> Result<NsProxy> {
|
||||
check_unsupported_ns_flags(flags)?;
|
||||
|
||||
let inode_handle = file
|
||||
.downcast_ref::<InodeHandle>()
|
||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "the file is not a ns file"))?;
|
||||
|
||||
let current_proxy = ctx.thread_local.borrow_ns_proxy();
|
||||
let current_proxy = current_proxy.unwrap();
|
||||
|
||||
let mut builder = NsProxyBuilder::new(current_proxy);
|
||||
|
||||
let applied = try_apply_ns::<UtsNamespace>(inode_handle, flags, |ns| {
|
||||
builder.uts_ns(ns);
|
||||
})? || try_apply_ns::<MountNamespace>(inode_handle, flags, |ns| {
|
||||
builder.mnt_ns(ns);
|
||||
})?;
|
||||
// TODO: Support setting other namespaces from the ns file.
|
||||
|
||||
if !applied {
|
||||
return_errno_with_message!(Errno::EINVAL, "invalid flags are specified with a ns file");
|
||||
}
|
||||
|
||||
Ok(builder.build())
|
||||
}
|
||||
|
||||
fn try_apply_ns<T: NsCommonOps>(
|
||||
inode_handle: &InodeHandle,
|
||||
flags: CloneFlags,
|
||||
apply: impl FnOnce(Arc<T>),
|
||||
) -> Result<bool> {
|
||||
let Some(ns_file) = inode_handle.as_ns_file::<T>() else {
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
if !flags.is_empty() && flags != T::TYPE.into() {
|
||||
return_errno_with_message!(
|
||||
Errno::EINVAL,
|
||||
"the flags do not match the type of the ns file"
|
||||
);
|
||||
}
|
||||
|
||||
apply(ns_file.ns().clone());
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn set_uts_ns(
|
||||
builder: &mut NsProxyBuilder,
|
||||
target_ns: &Arc<UtsNamespace>,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ TESTS ?= \
|
|||
sched_yield_test \
|
||||
semaphore_test \
|
||||
sendfile_test \
|
||||
setns_test \
|
||||
sigaction_test \
|
||||
sigaltstack_test \
|
||||
signalfd_test \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
SetnsTest.ChangeIPCNamespace
|
||||
SetnsTest.ChangePIDNamespace
|
||||
Loading…
Reference in New Issue