Some CStr related changes
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
61bfa35549
commit
275009ec68
28
src/fork.rs
28
src/fork.rs
@ -20,7 +20,7 @@ use crate::{libc_try, libc_wrap};
|
||||
|
||||
pub async fn forking_syscall<F>(func: F) -> io::Result<SyscallStatus>
|
||||
where
|
||||
F: FnOnce() -> Result<i64, Errno> + UnwindSafe,
|
||||
F: FnOnce() -> io::Result<SyscallStatus> + UnwindSafe,
|
||||
{
|
||||
let mut fork = Fork::new(func)?;
|
||||
let result = fork.get_result().await?;
|
||||
@ -47,12 +47,13 @@ impl Drop for Fork {
|
||||
struct Data {
|
||||
val: i64,
|
||||
error: i32,
|
||||
failure: i32,
|
||||
}
|
||||
|
||||
impl Fork {
|
||||
pub fn new<F>(func: F) -> io::Result<Self>
|
||||
where
|
||||
F: FnOnce() -> Result<i64, Errno> + UnwindSafe,
|
||||
F: FnOnce() -> io::Result<SyscallStatus> + UnwindSafe,
|
||||
{
|
||||
let mut pipe: [c_int; 2] = [0, 0];
|
||||
libc_try!(unsafe { libc::pipe2(pipe.as_mut_ptr(), libc::O_CLOEXEC | libc::O_NONBLOCK) });
|
||||
@ -65,13 +66,20 @@ impl Fork {
|
||||
|
||||
let _ = std::panic::catch_unwind(move || {
|
||||
let out = match func() {
|
||||
Ok(val) => Data {
|
||||
Ok(SyscallStatus::Ok(val)) => Data {
|
||||
val,
|
||||
error: 0,
|
||||
failure: 0,
|
||||
},
|
||||
Err(error) => Data {
|
||||
Ok(SyscallStatus::Err(error)) => Data {
|
||||
val: -1,
|
||||
error: error as _,
|
||||
failure: 0,
|
||||
},
|
||||
Err(err) => Data {
|
||||
val: -1,
|
||||
error: -1,
|
||||
failure: err.raw_os_error().unwrap_or(libc::EFAULT),
|
||||
},
|
||||
};
|
||||
|
||||
@ -118,7 +126,10 @@ impl Fork {
|
||||
}
|
||||
|
||||
if status != 0 {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "error in child process"))
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"error in child process",
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@ -133,8 +144,11 @@ impl Fork {
|
||||
&mut data as *mut Data as *mut u8,
|
||||
std::mem::size_of::<Data>(),
|
||||
)
|
||||
}).await?;
|
||||
if data.error == 0 {
|
||||
})
|
||||
.await?;
|
||||
if data.failure != 0 {
|
||||
Err(io::Error::from_raw_os_error(data.failure))
|
||||
} else if data.error == 0 {
|
||||
Ok(SyscallStatus::Ok(data.val))
|
||||
} else {
|
||||
Ok(SyscallStatus::Err(data.error))
|
||||
|
25
src/nsfd.rs
25
src/nsfd.rs
@ -1,10 +1,10 @@
|
||||
use std::ffi::CStr;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_int;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::tools::path_ptr;
|
||||
use crate::{file_descriptor_type, libc_try};
|
||||
|
||||
pub mod ns_type {
|
||||
@ -31,18 +31,13 @@ pub use ns_type::NsType;
|
||||
file_descriptor_type!(RawNsFd);
|
||||
|
||||
impl RawNsFd {
|
||||
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
||||
Self::openat(libc::AT_FDCWD, path.as_ref())
|
||||
pub fn open(path: &CStr) -> io::Result<Self> {
|
||||
Self::openat(libc::AT_FDCWD, path)
|
||||
}
|
||||
|
||||
pub fn openat<P: AsRef<Path>>(fd: RawFd, path: P) -> io::Result<Self> {
|
||||
let fd = libc_try!(unsafe {
|
||||
libc::openat(
|
||||
fd,
|
||||
path_ptr(path.as_ref()),
|
||||
libc::O_RDONLY | libc::O_CLOEXEC,
|
||||
)
|
||||
});
|
||||
pub fn openat(fd: RawFd, path: &CStr) -> io::Result<Self> {
|
||||
let fd =
|
||||
libc_try!(unsafe { libc::openat(fd, path.as_ptr(), libc::O_RDONLY | libc::O_CLOEXEC) });
|
||||
|
||||
Ok(Self(fd))
|
||||
}
|
||||
@ -65,12 +60,12 @@ impl<T: NsType> std::ops::Deref for NsFd<T> {
|
||||
}
|
||||
|
||||
impl<T: NsType> NsFd<T> {
|
||||
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
||||
Ok(Self(RawNsFd::open(path.as_ref())?, PhantomData))
|
||||
pub fn open(path: &CStr) -> io::Result<Self> {
|
||||
Ok(Self(RawNsFd::open(path)?, PhantomData))
|
||||
}
|
||||
|
||||
pub fn openat<P: AsRef<Path>>(fd: RawFd, path: P) -> io::Result<Self> {
|
||||
Ok(Self(RawNsFd::openat(fd, path.as_ref())?, PhantomData))
|
||||
pub fn openat(fd: RawFd, path: &CStr) -> io::Result<Self> {
|
||||
Ok(Self(RawNsFd::openat(fd, path)?, PhantomData))
|
||||
}
|
||||
|
||||
pub fn setns(&self) -> io::Result<()> {
|
||||
|
20
src/pidfd.rs
20
src/pidfd.rs
@ -1,6 +1,6 @@
|
||||
//! pidfd helper functionality
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::io;
|
||||
use std::os::raw::c_int;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
|
||||
@ -22,15 +22,21 @@ impl PidFd {
|
||||
}
|
||||
|
||||
pub fn mount_namespace(&self) -> io::Result<NsFd<ns_type::Mount>> {
|
||||
NsFd::openat(self.0, "ns/mnt")
|
||||
NsFd::openat(self.0, unsafe {
|
||||
CStr::from_bytes_with_nul_unchecked(b"ns/mnt\0")
|
||||
})
|
||||
}
|
||||
|
||||
pub fn cgroup_namespace(&self) -> io::Result<NsFd<ns_type::Cgroup>> {
|
||||
NsFd::openat(self.0, "ns/cgroup")
|
||||
NsFd::openat(self.0, unsafe {
|
||||
CStr::from_bytes_with_nul_unchecked(b"ns/cgroup\0")
|
||||
})
|
||||
}
|
||||
|
||||
pub fn user_namespace(&self) -> io::Result<NsFd<ns_type::User>> {
|
||||
NsFd::openat(self.0, "ns/user")
|
||||
NsFd::openat(self.0, unsafe {
|
||||
CStr::from_bytes_with_nul_unchecked(b"ns/user\0")
|
||||
})
|
||||
}
|
||||
|
||||
fn fd(&self, path: &[u8], flags: c_int) -> io::Result<Fd> {
|
||||
@ -50,4 +56,10 @@ impl PidFd {
|
||||
pub fn fd_num(&self, num: RawFd, flags: c_int) -> io::Result<Fd> {
|
||||
self.fd(format!("fd/{}\0", num).as_bytes(), flags)
|
||||
}
|
||||
|
||||
//pub fn dup(&self) -> io::Result<Self> {
|
||||
// Ok(Self(libc_try!(unsafe {
|
||||
// libc::fcntl(self.as_raw_fd(), libc::F_DUPFD_CLOEXEC, 0)
|
||||
// })))
|
||||
//}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::ffi::CString;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||
|
||||
use failure::Error;
|
||||
use nix::errno::Errno;
|
||||
@ -6,6 +7,7 @@ use nix::sys::stat;
|
||||
|
||||
use crate::fork::forking_syscall;
|
||||
use crate::lxcseccomp::ProxyMessageBuffer;
|
||||
use crate::pidfd::PidFd;
|
||||
use crate::syscall::SyscallStatus;
|
||||
use crate::tools::Fd;
|
||||
|
||||
@ -14,7 +16,9 @@ pub async fn mknod(msg: &ProxyMessageBuffer) -> Result<SyscallStatus, Error> {
|
||||
let mode = msg.arg_mode_t(1)?;
|
||||
let dev = msg.arg_dev_t(2)?;
|
||||
let cwd = msg.pid_fd().fd_cwd()?;
|
||||
do_mknodat(cwd, pathname, mode, dev).await
|
||||
|
||||
let pidfd = unsafe { PidFd::from_raw_fd(msg.pid_fd().as_raw_fd()) };
|
||||
do_mknodat(pidfd, cwd, pathname, mode, dev).await
|
||||
}
|
||||
|
||||
pub async fn mknodat(msg: &ProxyMessageBuffer) -> Result<SyscallStatus, Error> {
|
||||
@ -22,17 +26,24 @@ pub async fn mknodat(msg: &ProxyMessageBuffer) -> Result<SyscallStatus, Error> {
|
||||
let pathname = msg.arg_c_string(1)?;
|
||||
let mode = msg.arg_mode_t(2)?;
|
||||
let dev = msg.arg_dev_t(3)?;
|
||||
do_mknodat(dirfd, pathname, mode, dev).await
|
||||
|
||||
let pidfd = unsafe { PidFd::from_raw_fd(msg.pid_fd().as_raw_fd()) };
|
||||
do_mknodat(pidfd, dirfd, pathname, mode, dev).await
|
||||
}
|
||||
|
||||
async fn do_mknodat(
|
||||
_dirfd: Fd,
|
||||
pidfd: PidFd,
|
||||
dirfd: Fd,
|
||||
_pathname: CString,
|
||||
_mode: stat::mode_t,
|
||||
_dev: stat::dev_t,
|
||||
) -> Result<SyscallStatus, Error> {
|
||||
println!("=> Responding with ENOENT");
|
||||
Ok(forking_syscall(move || {
|
||||
Err(Errno::ENOENT)
|
||||
}).await?)
|
||||
pidfd.mount_namespace()?.setns()?;
|
||||
std::mem::drop(pidfd);
|
||||
std::mem::drop(dirfd);
|
||||
Ok(SyscallStatus::Err(libc::ENOENT))
|
||||
})
|
||||
.await?)
|
||||
}
|
||||
|
@ -299,9 +299,3 @@ macro_rules! libc_try {
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
pub fn path_ptr(path: &std::path::Path) -> *const libc::c_char {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
path.as_os_str().as_bytes().as_ptr() as *const libc::c_char
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user