Merge branch 'bind-connect-redoxfs' into 'master'
feat: Integrate UDS bind and connect operation with RedoxFS and switch get_proc_credentials to a capability-based approach. See merge request redox-os/relibc!665
This commit is contained in:
Generated
+2
-2
@@ -432,9 +432,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox-path"
|
||||
version = "0.2.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7"
|
||||
checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
|
||||
|
||||
[[package]]
|
||||
name = "redox-rt"
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ sc = "0.2.3"
|
||||
[target.'cfg(target_os = "redox")'.dependencies]
|
||||
redox_syscall = "0.5.13"
|
||||
redox-rt = { path = "redox-rt" }
|
||||
redox-path = "0.2"
|
||||
redox-path = "0.3"
|
||||
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git", default-features = false, features = [
|
||||
"redox_syscall",
|
||||
] }
|
||||
|
||||
@@ -52,6 +52,7 @@ pub enum ThreadCall {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(usize)]
|
||||
#[non_exhaustive]
|
||||
pub enum SocketCall {
|
||||
Bind = 0,
|
||||
Connect = 1,
|
||||
@@ -59,6 +60,15 @@ pub enum SocketCall {
|
||||
GetSockOpt = 3,
|
||||
SendMsg = 4,
|
||||
RecvMsg = 5,
|
||||
Unbind = 6,
|
||||
GetToken = 7,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(usize)]
|
||||
#[non_exhaustive]
|
||||
pub enum FsCall {
|
||||
Connect = 0,
|
||||
}
|
||||
|
||||
impl ProcCall {
|
||||
@@ -103,6 +113,17 @@ impl SocketCall {
|
||||
3 => Self::GetSockOpt,
|
||||
4 => Self::SendMsg,
|
||||
5 => Self::RecvMsg,
|
||||
6 => Self::Unbind,
|
||||
7 => Self::GetToken,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FsCall {
|
||||
pub fn try_from_raw(raw: usize) -> Option<Self> {
|
||||
Some(match raw {
|
||||
0 => Self::Connect,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
+3
-2
@@ -296,11 +296,12 @@ pub fn posix_getresugid() -> Resugid<u32> {
|
||||
sgid,
|
||||
}
|
||||
}
|
||||
pub fn get_proc_credentials(target_pid: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
pub fn get_proc_credentials(cap_fd: usize, target_pid: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
if buf.len() < size_of::<crate::protocol::ProcMeta>() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
this_proc_call(
|
||||
proc_call(
|
||||
cap_fd,
|
||||
buf,
|
||||
CallFlags::empty(),
|
||||
&[ProcCall::GetProcCredentials as u64, target_pid as u64],
|
||||
|
||||
@@ -242,11 +242,12 @@ pub unsafe extern "C" fn redox_get_rgid_v1() -> RawResult {
|
||||
redox_rt::sys::posix_getresugid().rgid as _
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn redox_get_proc_credentials_v0(
|
||||
pub unsafe extern "C" fn redox_get_proc_credentials_v1(
|
||||
cap_fd: usize,
|
||||
target_pid: usize,
|
||||
buf: &mut [u8],
|
||||
) -> RawResult {
|
||||
Error::mux(redox_rt::sys::get_proc_credentials(target_pid, buf))
|
||||
Error::mux(redox_rt::sys::get_proc_credentials(cap_fd, target_pid, buf))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
|
||||
use alloc::{
|
||||
borrow::ToOwned,
|
||||
boxed::Box,
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use redox_rt::signal::tmp_disable_signals;
|
||||
use syscall::{data::Stat, error::*, flag::*};
|
||||
|
||||
use super::{libcscheme, FdGuard};
|
||||
use crate::sync::Mutex;
|
||||
|
||||
pub use redox_path::canonicalize_using_cwd;
|
||||
pub use redox_path::{canonicalize_using_cwd, RedoxPath};
|
||||
|
||||
// TODO: Define in syscall
|
||||
const PATH_MAX: usize = 4096;
|
||||
@@ -169,3 +174,40 @@ pub fn open(path: &str, flags: usize) -> Result<usize> {
|
||||
}
|
||||
Err(Error::new(ELOOP))
|
||||
}
|
||||
|
||||
pub fn dir_path_and_fd_path(socket_path: &str) -> Result<(String, String)> {
|
||||
let _siglock = tmp_disable_signals();
|
||||
let cwd_guard = CWD.lock();
|
||||
|
||||
let full_path = canonicalize_with_cwd_internal(cwd_guard.as_deref(), socket_path)?;
|
||||
|
||||
let redox_path = RedoxPath::from_absolute(&full_path).ok_or(Error::new(EINVAL))?;
|
||||
let (_, mut ref_path) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
if ref_path.as_ref().is_empty() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
if redox_path.is_default_scheme() {
|
||||
let dir_to_open = String::from(get_parent_path(&full_path).ok_or(Error::new(EINVAL))?);
|
||||
Ok((dir_to_open, ref_path.as_ref().to_string()))
|
||||
} else {
|
||||
let full_path = canonicalize_with_cwd_internal(cwd_guard.as_deref(), ref_path.as_ref())?;
|
||||
let redox_path = RedoxPath::from_absolute(&full_path).ok_or(Error::new(EINVAL))?;
|
||||
let (_, path) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
let dir_to_open = String::from(get_parent_path(&full_path).ok_or(Error::new(EINVAL))?);
|
||||
Ok((dir_to_open, path.as_ref().to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_parent_path(path: &str) -> Option<&str> {
|
||||
path.rfind('/').and_then(|index| {
|
||||
if index == 0 {
|
||||
// Path is something like "/file.txt" or the root "/".
|
||||
// The parent is the root directory "/".
|
||||
Some("/")
|
||||
} else {
|
||||
// Path is something like "/a/b/c.txt".
|
||||
// Take the slice from the beginning up to the last '/'.
|
||||
Some(&path[..index])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use core::{cmp, mem, ptr, slice, str};
|
||||
use redox_rt::{proc::FdGuard, protocol::SocketCall};
|
||||
use redox_rt::{
|
||||
proc::FdGuard,
|
||||
protocol::{FsCall, SocketCall},
|
||||
};
|
||||
use syscall::{self, flag::*};
|
||||
|
||||
use super::{
|
||||
super::{types::*, Pal, PalSocket, ERRNO},
|
||||
path::dir_path_and_fd_path,
|
||||
Sys,
|
||||
};
|
||||
use crate::{
|
||||
@@ -522,15 +526,40 @@ impl PalSocket for Sys {
|
||||
);
|
||||
|
||||
let addr = slice::from_raw_parts(&data.sun_path as *const _ as *const u8, len);
|
||||
let mut path = format!("{}", str::from_utf8(addr).unwrap());
|
||||
let path = format!("{}", str::from_utf8(addr).unwrap());
|
||||
trace!("path: {:?}", path);
|
||||
|
||||
let (dir_path, mut fd_path) = dir_path_and_fd_path(&path)?;
|
||||
|
||||
redox_rt::sys::sys_call(
|
||||
socket as usize,
|
||||
path.as_bytes_mut(),
|
||||
fd_path.as_bytes_mut(),
|
||||
CallFlags::empty(),
|
||||
&[SocketCall::Bind as u64],
|
||||
)?;
|
||||
|
||||
let fs_bind_result = (|| -> Result<()> {
|
||||
let dirfd = FdGuard::new(syscall::open(
|
||||
&dir_path,
|
||||
syscall::O_RDONLY | syscall::O_DIRECTORY | syscall::O_CLOEXEC,
|
||||
)?);
|
||||
let fd_to_send = FdGuard::new(syscall::dup(socket as usize, &[])?);
|
||||
let _ = syscall::sendfd(*dirfd, *fd_to_send, 0, 0)?;
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
if let Err(original_error) = fs_bind_result {
|
||||
if let Err(unbind_error) = redox_rt::sys::sys_call(
|
||||
socket as usize,
|
||||
&mut [],
|
||||
CallFlags::empty(),
|
||||
&[SocketCall::Unbind as u64],
|
||||
) {
|
||||
eprintln!("bind: CRITICAL: failed to unbind socket after a failed transaction: {:?}", unbind_error);
|
||||
}
|
||||
|
||||
return Err(original_error);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Errno(EAFNOSUPPORT));
|
||||
@@ -570,9 +599,25 @@ impl PalSocket for Sys {
|
||||
let mut path = format!("{}", str::from_utf8(addr).unwrap());
|
||||
trace!("path: {:?}", path);
|
||||
|
||||
let (_, fd_path) = dir_path_and_fd_path(&path)?;
|
||||
|
||||
let target_path = format!("/{fd_path}");
|
||||
let socket_file_fd = FdGuard::new(syscall::open(&target_path, syscall::O_RDWR)?);
|
||||
|
||||
const TOKEN_BUF_SIZE: usize = 16;
|
||||
|
||||
let mut token_buf = [0u8; TOKEN_BUF_SIZE];
|
||||
|
||||
redox_rt::sys::sys_call(
|
||||
*socket_file_fd,
|
||||
&mut token_buf,
|
||||
CallFlags::empty(),
|
||||
&[FsCall::Connect as u64],
|
||||
)?;
|
||||
|
||||
redox_rt::sys::sys_call(
|
||||
socket as usize,
|
||||
path.as_bytes_mut(),
|
||||
&mut token_buf,
|
||||
CallFlags::empty(),
|
||||
&[SocketCall::Connect as u64],
|
||||
)?;
|
||||
|
||||
Reference in New Issue
Block a user