base: apply Red Bear patches on latest upstream/main
251 files: init, acpid, ipcd, netcfg, ihdgd, virtio-gpud, scheme-utils, inputd, block driver, ptyd, ramfs, randd, initfs bootstrap, path deps, version +rb0.3.1, author attribution
This commit is contained in:
+39
-49
@@ -6,11 +6,10 @@ use core::str::FromStr;
|
||||
use hashbrown::HashMap;
|
||||
use redox_scheme::Socket;
|
||||
|
||||
use libredox::protocol::O_CLOEXEC;
|
||||
use syscall::data::{GlobalSchemes, KernelSchemeInfo};
|
||||
use syscall::flag::{O_DIRECTORY, O_RDONLY, O_STAT};
|
||||
use syscall::CallFlags;
|
||||
use syscall::{Error, EINTR};
|
||||
use syscall::data::{GlobalSchemes, KernelSchemeInfo};
|
||||
use syscall::flag::{O_CLOEXEC, O_RDONLY, O_STAT};
|
||||
use syscall::{EINTR, Error};
|
||||
|
||||
use redox_rt::proc::*;
|
||||
|
||||
@@ -27,7 +26,7 @@ impl log::Log for Logger {
|
||||
let line = record.line().unwrap_or(0);
|
||||
let level = record.level();
|
||||
let msg = record.args();
|
||||
let _ = syscall::write(
|
||||
let _ = libredox::call::write(
|
||||
1,
|
||||
alloc::format!("[{file}:{line} {level}] {msg}\n").as_bytes(),
|
||||
);
|
||||
@@ -54,8 +53,6 @@ pub fn main() -> ! {
|
||||
FdGuard::new(*(base_ptr as *const usize))
|
||||
};
|
||||
|
||||
let cur_context_idx = scheme_creation_cap.as_raw_fd() + 1;
|
||||
|
||||
let mut kernel_schemes = KernelSchemeMap::new(kernel_scheme_infos);
|
||||
|
||||
let auth = kernel_schemes
|
||||
@@ -63,8 +60,8 @@ pub fn main() -> ! {
|
||||
.remove(&GlobalSchemes::Proc)
|
||||
.expect("failed to get proc fd");
|
||||
|
||||
let this_thr_fd = syscall::dup_into(auth.as_raw_fd(), cur_context_idx, b"cur-context")
|
||||
.map(FdGuard::new)
|
||||
let this_thr_fd = auth
|
||||
.dup(b"cur-context")
|
||||
.expect("failed to open open_via_dup")
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
@@ -73,13 +70,13 @@ pub fn main() -> ! {
|
||||
let mut env_bytes = [0_u8; 4096];
|
||||
let mut envs = {
|
||||
let fd = FdGuard::new(
|
||||
redox_rt::sys::openat(
|
||||
libredox::call::openat(
|
||||
kernel_schemes
|
||||
.get(GlobalSchemes::Sys)
|
||||
.expect("failed to get sys fd")
|
||||
.as_raw_fd(),
|
||||
"env",
|
||||
O_RDONLY | O_CLOEXEC,
|
||||
(O_RDONLY | O_CLOEXEC) as i32,
|
||||
0,
|
||||
)
|
||||
.expect("bootstrap: failed to open env"),
|
||||
@@ -208,16 +205,12 @@ pub fn main() -> ! {
|
||||
// from this point, this_thr_fd is no longer valid
|
||||
|
||||
const CWD: &[u8] = b"/scheme/initfs";
|
||||
|
||||
let initfs_root_fd = initns_fd
|
||||
.openat_into_upper("/scheme/initfs", O_DIRECTORY, 0)
|
||||
.expect("failed to open initfs root fd");
|
||||
let cwd_fd = initfs_root_fd
|
||||
.openat_into_upper("", O_STAT, 0)
|
||||
.expect("failed to open cwd fd");
|
||||
let filetable_binary_fd = init_thr_fd
|
||||
.dup_into_upper(b"filetable-binary")
|
||||
.expect("faild to create filetable-binary fd");
|
||||
let cwd_fd = FdGuard::new(
|
||||
libredox::call::openat(initns_fd.as_raw_fd(), "/scheme/initfs", O_STAT as i32, 0)
|
||||
.expect("failed to open cwd fd"),
|
||||
)
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
let extrainfo = ExtraInfo {
|
||||
cwd: Some(CWD),
|
||||
sigprocmask: 0,
|
||||
@@ -227,18 +220,18 @@ pub fn main() -> ! {
|
||||
proc_fd: init_proc_fd.as_raw_fd(),
|
||||
ns_fd: Some(initns_fd.take()),
|
||||
cwd_fd: Some(cwd_fd.as_raw_fd()),
|
||||
filetable_fd: Some(filetable_binary_fd.as_raw_fd()),
|
||||
same_process: true,
|
||||
};
|
||||
|
||||
let exe_path = "/scheme/initfs/bin/init";
|
||||
let exe_reference = "bin/init";
|
||||
let path = "/scheme/initfs/bin/init";
|
||||
|
||||
let image_file = initfs_root_fd
|
||||
.openat_into_upper(exe_reference, O_RDONLY | O_CLOEXEC, 0)
|
||||
.expect("failed to open init");
|
||||
let image_file = FdGuard::new(
|
||||
libredox::call::openat(extrainfo.ns_fd.unwrap(), path, (O_RDONLY | O_CLOEXEC) as i32, 0)
|
||||
.expect("failed to open init"),
|
||||
)
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
|
||||
drop(initfs_root_fd);
|
||||
let exe_path = alloc::format!("/scheme/initfs{}", path);
|
||||
|
||||
let FexecResult::Interp {
|
||||
path: interp_path,
|
||||
@@ -253,33 +246,26 @@ pub fn main() -> ! {
|
||||
&extrainfo,
|
||||
None,
|
||||
)
|
||||
.ok()
|
||||
.flatten()
|
||||
.map_err(|e| {
|
||||
let _ = libredox::call::write(1, alloc::format!("fexec_impl failed: {}\n", e).as_bytes());
|
||||
e
|
||||
})
|
||||
.expect("failed to execute init");
|
||||
|
||||
// According to elf(5), PT_INTERP requires that the interpreter path be
|
||||
// null-terminated. Violating this should therefore give the "format error" ENOEXEC.
|
||||
let interp_cstr = CStr::from_bytes_with_nul(&interp_path).expect("interpreter not valid C str");
|
||||
let interp_path = interp_cstr.to_str().expect("interpreter not UTF-8");
|
||||
let root_fd = FdGuard::new(
|
||||
redox_rt::sys::openat_into_upper(
|
||||
let interp_file = FdGuard::new(
|
||||
libredox::call::openat(
|
||||
extrainfo.ns_fd.unwrap(), // initns, not initfs!
|
||||
interp_path,
|
||||
O_RDONLY | O_CLOEXEC,
|
||||
interp_cstr.to_str().expect("interpreter not UTF-8"),
|
||||
(O_RDONLY | O_CLOEXEC) as i32,
|
||||
0,
|
||||
)
|
||||
.expect("failed to open root fd"),
|
||||
.expect("failed to open dynamic linker"),
|
||||
)
|
||||
.to_upper()
|
||||
.unwrap();
|
||||
let redox_path = redox_path::RedoxPath::from_absolute(interp_path)
|
||||
.expect("interpreter path is not a Scheme-rooted path");
|
||||
let (_, reference) = redox_path
|
||||
.as_parts()
|
||||
.expect("redox_path is not scheme root path");
|
||||
let interp_file = root_fd
|
||||
.openat_into_upper(reference.as_ref(), O_RDONLY | O_CLOEXEC, 0)
|
||||
.expect("failed to open dynamic linker");
|
||||
|
||||
fexec_impl(
|
||||
interp_file,
|
||||
@@ -306,13 +292,13 @@ pub(crate) fn spawn(
|
||||
inner: impl FnOnce(FdGuard, Socket, FdGuard, KernelSchemeMap) -> !,
|
||||
) -> (FdGuard, FdGuard, KernelSchemeMap, FdGuard) {
|
||||
let read = FdGuard::new(
|
||||
redox_rt::sys::openat(
|
||||
libredox::call::openat(
|
||||
kernel_schemes
|
||||
.get(GlobalSchemes::Pipe)
|
||||
.expect("failed to get pipe fd")
|
||||
.as_raw_fd(),
|
||||
"",
|
||||
O_CLOEXEC,
|
||||
O_CLOEXEC as i32,
|
||||
0,
|
||||
)
|
||||
.expect("failed to open sync read pipe"),
|
||||
@@ -320,7 +306,7 @@ pub(crate) fn spawn(
|
||||
|
||||
// The write pipe will not inherit O_CLOEXEC, but is closed by the daemon later.
|
||||
let write = FdGuard::new(
|
||||
redox_rt::sys::dup(read.as_raw_fd(), b"write").expect("failed to open sync write pipe"),
|
||||
libredox::call::dup(read.as_raw_fd(), b"write").expect("failed to open sync write pipe"),
|
||||
);
|
||||
|
||||
match fork_impl(&ForkArgs::Init {
|
||||
@@ -332,11 +318,15 @@ pub(crate) fn spawn(
|
||||
}
|
||||
// Continue serving the scheme as the child.
|
||||
Ok(0) => {
|
||||
let _ = libredox::call::write(1, b"SP:0\n");
|
||||
drop(read);
|
||||
let _ = libredox::call::write(1, b"SP:1\n");
|
||||
|
||||
let socket = Socket::create_inner(scheme_creation_cap.as_raw_fd(), nonblock)
|
||||
.expect("failed to open proc scheme socket");
|
||||
let _ = libredox::call::write(1, b"SP:2\n");
|
||||
drop(scheme_creation_cap);
|
||||
let _ = libredox::call::write(1, b"SP:3\n");
|
||||
|
||||
inner(write, socket, auth, kernel_schemes)
|
||||
}
|
||||
@@ -352,7 +342,7 @@ pub(crate) fn spawn(
|
||||
)
|
||||
};
|
||||
loop {
|
||||
match redox_rt::sys::sys_call_ro(
|
||||
match syscall::call_ro(
|
||||
read.as_raw_fd(),
|
||||
fd_bytes,
|
||||
CallFlags::FD | CallFlags::FD_UPPER,
|
||||
|
||||
+82
-24
@@ -6,15 +6,16 @@ use core::str;
|
||||
use alloc::string::String;
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use redox_initfs::{InitFs, Inode, InodeDir, InodeKind, InodeStruct};
|
||||
use redox_initfs::{InitFs, Inode, InodeDir, InodeKind, InodeStruct, types::Timespec};
|
||||
|
||||
use redox_rt::proc::FdGuard;
|
||||
use redox_scheme::{
|
||||
scheme::{SchemeState, SchemeSync},
|
||||
CallerCtx, OpenResult, RequestKind,
|
||||
scheme::{SchemeState, SchemeSync},
|
||||
};
|
||||
|
||||
use redox_scheme::{SignalBehavior, Socket};
|
||||
use syscall::PAGE_SIZE;
|
||||
use syscall::data::Stat;
|
||||
use syscall::dirent::DirEntry;
|
||||
use syscall::dirent::DirentBuf;
|
||||
@@ -22,7 +23,6 @@ use syscall::dirent::DirentKind;
|
||||
use syscall::error::*;
|
||||
use syscall::flag::*;
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
use syscall::PAGE_SIZE;
|
||||
|
||||
enum Handle {
|
||||
Node(Node),
|
||||
@@ -135,7 +135,7 @@ impl SchemeSync for InitFsScheme {
|
||||
// filter out double slashes (e.g. /usr//bin/...)
|
||||
.filter(|c| !c.is_empty());
|
||||
|
||||
let mut current_inode = self.fs.root_inode();
|
||||
let mut current_inode = InitFs::ROOT_INODE;
|
||||
|
||||
while let Some(component) = components.next() {
|
||||
match component {
|
||||
@@ -315,6 +315,8 @@ impl SchemeSync for InitFsScheme {
|
||||
fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
|
||||
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?.as_node()?;
|
||||
|
||||
let Timespec { sec, nsec } = self.fs.image_creation_time();
|
||||
|
||||
let inode = Self::get_inode(&self.fs, handle.inode)?;
|
||||
|
||||
stat.st_ino = inode.id();
|
||||
@@ -329,10 +331,10 @@ impl SchemeSync for InitFsScheme {
|
||||
stat.st_gid = 0;
|
||||
stat.st_size = u64::try_from(inode_len(inode)?).unwrap_or(u64::MAX);
|
||||
|
||||
stat.st_ctime = 0;
|
||||
stat.st_ctime_nsec = 0;
|
||||
stat.st_mtime = 0;
|
||||
stat.st_mtime_nsec = 0;
|
||||
stat.st_ctime = sec.get();
|
||||
stat.st_ctime_nsec = nsec.get();
|
||||
stat.st_mtime = sec.get();
|
||||
stat.st_mtime_nsec = nsec.get();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -391,9 +393,9 @@ pub fn run(bytes: &'static [u8], sync_pipe: FdGuard, socket: Socket) -> ! {
|
||||
let cap_fd = socket
|
||||
.create_this_scheme_fd(0, new_id, 0, 0)
|
||||
.expect("failed to issue initfs root fd");
|
||||
let _ = redox_rt::sys::sys_call_wo(
|
||||
let _ = syscall::call_rw(
|
||||
sync_pipe.as_raw_fd(),
|
||||
&cap_fd.to_ne_bytes(),
|
||||
&mut cap_fd.to_ne_bytes(),
|
||||
CallFlags::FD,
|
||||
&[],
|
||||
);
|
||||
@@ -444,21 +446,72 @@ pub unsafe extern "C" fn redox_write_v1(fd: usize, ptr: *const u8, len: usize) -
|
||||
})) as isize
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_openat_v1(
|
||||
fd: usize,
|
||||
buf: *const u8,
|
||||
path_len: usize,
|
||||
flags: u32,
|
||||
fcntl_flags: u32,
|
||||
) -> isize {
|
||||
let path = unsafe { core::slice::from_raw_parts(buf, path_len) };
|
||||
let path_str = match core::str::from_utf8(path) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return -(syscall::EINVAL as isize),
|
||||
};
|
||||
Error::mux(syscall::openat(fd, path_str, flags as usize, fcntl_flags as usize)) as isize
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe fn redox_dup_v1(fd: usize, buf: *const u8, len: usize) -> isize {
|
||||
Error::mux(redox_rt::sys::dup(fd, unsafe {
|
||||
Error::mux(syscall::dup(fd, unsafe {
|
||||
core::slice::from_raw_parts(buf, len)
|
||||
})) as isize
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe fn redox_fcntl_v0(fd: usize, cmd: usize, arg: usize) -> isize {
|
||||
Error::mux(redox_rt::sys::fcntl(fd, cmd, arg)) as isize
|
||||
pub extern "C" fn redox_close_v1(fd: usize) -> isize {
|
||||
Error::mux(syscall::close(fd)) as isize
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn redox_close_v1(fd: usize) -> isize {
|
||||
Error::mux(redox_rt::sys::close(fd)) as isize
|
||||
pub extern "C" fn redox_fcntl_v0(fd: usize, cmd: usize, arg: usize) -> isize {
|
||||
Error::mux(syscall::fcntl(fd, cmd, arg)) as isize
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn redox_strerror_v1(
|
||||
dst: *mut u8,
|
||||
dst_len: *mut usize,
|
||||
error: u32,
|
||||
) -> isize {
|
||||
let msg = match error {
|
||||
x if x == syscall::EPERM as u32 => "Operation not permitted",
|
||||
x if x == syscall::ENOENT as u32 => "No such file or directory",
|
||||
x if x == syscall::EINTR as u32 => "Interrupted system call",
|
||||
x if x == syscall::EIO as u32 => "I/O error",
|
||||
x if x == syscall::EBADF as u32 => "Bad file descriptor",
|
||||
x if x == syscall::EAGAIN as u32 => "Resource temporarily unavailable",
|
||||
x if x == syscall::ENOMEM as u32 => "Cannot allocate memory",
|
||||
x if x == syscall::EACCES as u32 => "Permission denied",
|
||||
x if x == syscall::EFAULT as u32 => "Bad address",
|
||||
x if x == syscall::EBUSY as u32 => "Device or resource busy",
|
||||
x if x == syscall::EEXIST as u32 => "File exists",
|
||||
x if x == syscall::ENOTDIR as u32 => "Not a directory",
|
||||
x if x == syscall::EISDIR as u32 => "Is a directory",
|
||||
x if x == syscall::EINVAL as u32 => "Invalid argument",
|
||||
x if x == syscall::ENOSYS as u32 => "Function not implemented",
|
||||
x if x == syscall::ENOTEMPTY as u32 => "Directory not empty",
|
||||
_ => "Unknown error",
|
||||
};
|
||||
let msg_bytes = msg.as_bytes();
|
||||
unsafe {
|
||||
let avail = *dst_len;
|
||||
let copy_len = avail.min(msg_bytes.len());
|
||||
core::ptr::copy_nonoverlapping(msg_bytes.as_ptr(), dst, copy_len);
|
||||
*dst_len = copy_len;
|
||||
copy_len as isize
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -471,15 +524,20 @@ pub unsafe extern "C" fn redox_sys_call_v0(
|
||||
metadata_len: usize,
|
||||
) -> isize {
|
||||
let flags = CallFlags::from_bits_retain(flags);
|
||||
let read = flags.contains(syscall::CallFlags::READ);
|
||||
let write = flags.contains(syscall::CallFlags::WRITE);
|
||||
let payload = unsafe { core::slice::from_raw_parts_mut(payload, payload_len) };
|
||||
|
||||
let metadata = unsafe { core::slice::from_raw_parts(metadata, metadata_len) };
|
||||
|
||||
Error::mux(match (read, write) {
|
||||
(true, true) => redox_rt::sys::sys_call_rw(fd, payload, flags, metadata),
|
||||
(true, false) => redox_rt::sys::sys_call_ro(fd, payload, flags, metadata),
|
||||
(false, true) => redox_rt::sys::sys_call_wo(fd, payload, flags, metadata),
|
||||
(false, false) => redox_rt::sys::sys_call(fd, payload, flags, metadata),
|
||||
}) as isize
|
||||
let result = if flags.contains(CallFlags::READ) {
|
||||
let payload = unsafe { core::slice::from_raw_parts_mut(payload, payload_len) };
|
||||
if flags.contains(CallFlags::WRITE) {
|
||||
syscall::call_rw(fd, payload, flags, metadata)
|
||||
} else {
|
||||
syscall::call_ro(fd, payload, flags, metadata)
|
||||
}
|
||||
} else {
|
||||
let payload = unsafe { core::slice::from_raw_parts(payload, payload_len) };
|
||||
syscall::call_wo(fd, payload, flags, metadata)
|
||||
};
|
||||
|
||||
Error::mux(result) as isize
|
||||
}
|
||||
|
||||
+101
-150
@@ -10,14 +10,14 @@ use libredox::protocol::{NsDup, NsPermissions};
|
||||
use log::{error, warn};
|
||||
use redox_path::RedoxPath;
|
||||
use redox_path::RedoxScheme;
|
||||
use redox_rt::proc::{FdGuard, FdGuardUpper};
|
||||
use redox_rt::proc::FdGuard;
|
||||
use redox_scheme::{
|
||||
scheme::{SchemeState, SchemeSync},
|
||||
CallerCtx, OpenResult, RequestKind, Response, SendFdRequest, SignalBehavior, Socket,
|
||||
scheme::{SchemeState, SchemeSync},
|
||||
};
|
||||
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
|
||||
use syscall::Stat;
|
||||
use syscall::{error::*, schemev2::NewFdFlags, CallFlags, FobtainFdFlags};
|
||||
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
|
||||
use syscall::{CallFlags, FobtainFdFlags, error::*, schemev2::NewFdFlags};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Namespace {
|
||||
@@ -92,7 +92,6 @@ impl SchemeRegister {
|
||||
enum Handle {
|
||||
Access(NamespaceAccess),
|
||||
Register(SchemeRegister),
|
||||
OtherScheme { name: String, fd: Rc<FdGuard> },
|
||||
List(NamespaceAccess),
|
||||
}
|
||||
|
||||
@@ -101,7 +100,7 @@ pub struct NamespaceScheme<'sock> {
|
||||
handles: HashMap<usize, Handle>,
|
||||
root_namespace: Namespace,
|
||||
next_id: usize,
|
||||
scheme_creation_cap: Rc<FdGuardUpper>,
|
||||
scheme_creation_cap: FdGuard,
|
||||
}
|
||||
|
||||
const HIGH_PERMISSIONS: NsPermissions = NsPermissions::SCHEME_CREATE;
|
||||
@@ -110,14 +109,14 @@ impl<'sock> NamespaceScheme<'sock> {
|
||||
pub fn new(
|
||||
socket: &'sock Socket,
|
||||
schemes: HashMap<String, Arc<FdGuard>>,
|
||||
scheme_creation_cap: FdGuardUpper,
|
||||
scheme_creation_cap: FdGuard,
|
||||
) -> Self {
|
||||
Self {
|
||||
socket,
|
||||
handles: HashMap::new(),
|
||||
root_namespace: Namespace { schemes },
|
||||
next_id: 0,
|
||||
scheme_creation_cap: Rc::new(scheme_creation_cap),
|
||||
scheme_creation_cap,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,55 +137,23 @@ impl<'sock> NamespaceScheme<'sock> {
|
||||
}
|
||||
|
||||
fn open_namespace_resource(
|
||||
&mut self,
|
||||
&self,
|
||||
ns_access: &NamespaceAccess,
|
||||
redox_path: RedoxPath<'_>,
|
||||
reference: &str,
|
||||
_flags: usize,
|
||||
_fcntl_flags: u32,
|
||||
_ctx: &CallerCtx,
|
||||
) -> Result<usize> {
|
||||
let (_scheme, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
|
||||
match reference.as_ref() {
|
||||
match reference {
|
||||
"scheme-creation-cap" => {
|
||||
if !ns_access.has_permission(NsPermissions::SCHEME_CREATE) {
|
||||
error!("Permission denied to get scheme creation capability");
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let new_id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(new_id, Handle::List(ns_access.clone()));
|
||||
|
||||
let resource_id = self.next_id;
|
||||
self.next_id += 1;
|
||||
|
||||
let dup_fd = self.scheme_creation_cap.dup(&[])?;
|
||||
|
||||
self.handles.insert(
|
||||
resource_id,
|
||||
Handle::OtherScheme {
|
||||
name: redox_path.to_string(),
|
||||
fd: Rc::new(dup_fd),
|
||||
},
|
||||
);
|
||||
Ok(resource_id)
|
||||
}
|
||||
"" => {
|
||||
if !ns_access.has_permission(NsPermissions::LIST) {
|
||||
error!("Permission denied to list schemes in namespace root");
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let new_id = self.next_id;
|
||||
self.next_id += 1;
|
||||
|
||||
self.handles.insert(new_id, Handle::List(ns_access.clone()));
|
||||
|
||||
Ok(new_id)
|
||||
Ok(libredox::call::dup(self.scheme_creation_cap.as_raw_fd(), &[])?)
|
||||
}
|
||||
_ => {
|
||||
error!("Unknown special reference: {}", reference.as_ref());
|
||||
error!("Unknown special reference: {}", reference);
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
}
|
||||
@@ -196,19 +163,24 @@ impl<'sock> NamespaceScheme<'sock> {
|
||||
&self,
|
||||
ns: &Namespace,
|
||||
scheme: &str,
|
||||
reference: &str,
|
||||
flags: usize,
|
||||
_ctx: &CallerCtx,
|
||||
) -> Result<FdGuard> {
|
||||
fcntl_flags: u32,
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<usize> {
|
||||
let Some(cap_fd) = ns.get_scheme_fd(scheme) else {
|
||||
log::info!("Scheme {:?} not found in namespace", scheme);
|
||||
return Err(Error::new(ENODEV));
|
||||
};
|
||||
|
||||
if flags & syscall::O_DIRECTORY == 0 {
|
||||
return Err(Error::new(EISDIR));
|
||||
}
|
||||
let scheme_fd = syscall::openat(
|
||||
cap_fd.as_raw_fd(),
|
||||
reference,
|
||||
flags,
|
||||
fcntl_flags as usize,
|
||||
)?;
|
||||
|
||||
cap_fd.dup(&[])
|
||||
Ok(scheme_fd)
|
||||
}
|
||||
|
||||
fn fork_namespace(&mut self, namespace: Rc<RefCell<Namespace>>, names: &[u8]) -> Result<usize> {
|
||||
@@ -237,10 +209,6 @@ impl<'sock> NamespaceScheme<'sock> {
|
||||
self.next_id += 1;
|
||||
Ok(next_id)
|
||||
}
|
||||
|
||||
fn on_close(&mut self, id: usize) {
|
||||
let _ = self.handles.remove(&id);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
@@ -252,83 +220,55 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
fcntl_flags: u32,
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<OpenResult> {
|
||||
let handle = self.handles.get(&fd).cloned().ok_or_else(|| {
|
||||
error!("Handle with ID {} not found", fd);
|
||||
Error::new(ENOENT)
|
||||
})?;
|
||||
|
||||
match handle {
|
||||
Handle::Access(ns_access) => {
|
||||
let redox_path = RedoxPath::from_absolute(path).ok_or(Error::new(EINVAL))?;
|
||||
let (scheme, _reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
|
||||
match scheme.as_ref() {
|
||||
"namespace" | "" => {
|
||||
let new_id = self.open_namespace_resource(
|
||||
&ns_access,
|
||||
redox_path,
|
||||
flags,
|
||||
fcntl_flags,
|
||||
ctx,
|
||||
)?;
|
||||
Ok(OpenResult::ThisScheme {
|
||||
number: new_id,
|
||||
flags: NewFdFlags::empty(),
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
let res_fd = self.open_scheme_resource(
|
||||
&ns_access.namespace.borrow(),
|
||||
scheme.as_ref(),
|
||||
flags,
|
||||
ctx,
|
||||
)?;
|
||||
Ok(OpenResult::OtherScheme { fd: res_fd.take() })
|
||||
}
|
||||
}
|
||||
}
|
||||
Handle::List(ns_access) => {
|
||||
if path.is_empty() || path == "." {
|
||||
let new_id = self.next_id;
|
||||
self.next_id += 1;
|
||||
|
||||
self.handles.insert(new_id, Handle::List(ns_access.clone()));
|
||||
Ok(OpenResult::ThisScheme {
|
||||
number: new_id,
|
||||
flags: NewFdFlags::empty(),
|
||||
})
|
||||
} else {
|
||||
error!("Cannot open a path under List handle: {}", path);
|
||||
Err(Error::new(EINVAL))
|
||||
}
|
||||
}
|
||||
Handle::OtherScheme {
|
||||
name: saved_path_str,
|
||||
fd: target_fd,
|
||||
} => {
|
||||
let saved_path =
|
||||
RedoxPath::from_absolute(&saved_path_str).ok_or(Error::new(syscall::EPROTO))?;
|
||||
let (_scheme, reference) =
|
||||
saved_path.as_parts().ok_or(Error::new(syscall::EPROTO))?;
|
||||
|
||||
if reference.as_ref() == path {
|
||||
Ok(OpenResult::OtherScheme {
|
||||
fd: target_fd.dup(&[])?.take(),
|
||||
})
|
||||
} else {
|
||||
error!(
|
||||
"Resource path mismatch: expected {}, got {}",
|
||||
reference.as_ref(),
|
||||
path,
|
||||
);
|
||||
Err(Error::new(EINVAL))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
error!("Handle {} is not accessible for openat", fd);
|
||||
Err(Error::new(EBADF))
|
||||
let ns_access = {
|
||||
let handle = self.handles.get(&fd);
|
||||
match handle {
|
||||
Some(Handle::Access(access)) => Some(access),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
.ok_or_else(|| {
|
||||
error!("Namespace with ID {} not found", fd);
|
||||
Error::new(ENOENT)
|
||||
})?;
|
||||
let redox_path = RedoxPath::from_absolute(path).ok_or(Error::new(EINVAL))?;
|
||||
let (scheme, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let res_fd = match scheme.as_ref() {
|
||||
"namespace" => self.open_namespace_resource(
|
||||
ns_access,
|
||||
reference.as_ref(),
|
||||
flags,
|
||||
fcntl_flags,
|
||||
ctx,
|
||||
)?,
|
||||
"" => {
|
||||
if !ns_access.has_permission(NsPermissions::LIST) {
|
||||
error!("Permission denied to list schemes in namespace {}", fd);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let new_id = self.next_id;
|
||||
self.next_id += 1;
|
||||
|
||||
self.handles.insert(new_id, Handle::List(ns_access.clone()));
|
||||
|
||||
return Ok(OpenResult::ThisScheme {
|
||||
number: new_id,
|
||||
flags: NewFdFlags::empty(),
|
||||
});
|
||||
}
|
||||
_ => self.open_scheme_resource(
|
||||
&ns_access.namespace.borrow(),
|
||||
scheme.as_ref(),
|
||||
reference.as_ref(),
|
||||
flags,
|
||||
fcntl_flags,
|
||||
ctx,
|
||||
)?,
|
||||
};
|
||||
|
||||
Ok(OpenResult::OtherScheme { fd: res_fd })
|
||||
}
|
||||
|
||||
fn dup(&mut self, id: usize, buf: &[u8], _ctx: &CallerCtx) -> Result<OpenResult> {
|
||||
@@ -346,6 +286,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
let new_id = match kind {
|
||||
NsDup::ForkNs => {
|
||||
let ns = ns_access.namespace.clone();
|
||||
let _ = ns_access;
|
||||
self.fork_namespace(ns, payload)?
|
||||
}
|
||||
NsDup::ShrinkPermissions => self.shrink_permissions(
|
||||
@@ -383,7 +324,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
})
|
||||
}
|
||||
|
||||
fn unlinkat(&mut self, fd: usize, path: &str, _flags: usize, _ctx: &CallerCtx) -> Result<()> {
|
||||
fn unlinkat(&mut self, fd: usize, path: &str, flags: usize, ctx: &CallerCtx) -> Result<()> {
|
||||
let ns_access = self.get_ns_access(fd).ok_or_else(|| {
|
||||
error!("Namespace with ID {} not found", fd);
|
||||
Error::new(ENOENT)
|
||||
@@ -392,20 +333,31 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
|
||||
let redox_path = RedoxPath::from_absolute(path).ok_or(Error::new(EINVAL))?;
|
||||
let (scheme, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
if !reference.as_ref().is_empty() {
|
||||
return Err(Error::new(EXDEV));
|
||||
}
|
||||
if !ns_access.has_permission(NsPermissions::DELETE) {
|
||||
error!("Permission denied to remove scheme for namespace {}", fd);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
match ns.remove_scheme(scheme.as_ref()) {
|
||||
Some(_) => Ok(()),
|
||||
None => {
|
||||
error!("Scheme {} not found in namespace", scheme);
|
||||
Err(Error::new(ENODEV))
|
||||
if reference.as_ref().is_empty() {
|
||||
if !ns_access.has_permission(NsPermissions::DELETE) {
|
||||
error!("Permission denied to remove scheme for namespace {}", fd);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
match ns.remove_scheme(scheme.as_ref()) {
|
||||
Some(_) => return Ok(()),
|
||||
None => {
|
||||
error!("Scheme {} not found in namespace", scheme);
|
||||
return Err(Error::new(ENODEV));
|
||||
}
|
||||
}
|
||||
}
|
||||
let Some(cap_fd) = ns.get_scheme_fd(scheme.as_ref()) else {
|
||||
error!("Scheme {} not found in namespace", scheme);
|
||||
return Err(Error::new(ENODEV));
|
||||
};
|
||||
|
||||
syscall::unlinkat(cap_fd.as_raw_fd(), reference, flags)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_close(&mut self, id: usize) {
|
||||
self.handles.remove(&id);
|
||||
}
|
||||
|
||||
fn on_sendfd(&mut self, sendfd_request: &SendFdRequest) -> Result<usize> {
|
||||
@@ -433,7 +385,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
}
|
||||
let mut new_fd = usize::MAX;
|
||||
if let Err(e) = sendfd_request.obtain_fd(
|
||||
self.socket,
|
||||
&self.socket,
|
||||
FobtainFdFlags::UPPER_TBL,
|
||||
core::slice::from_mut(&mut new_fd),
|
||||
) {
|
||||
@@ -468,11 +420,12 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
}
|
||||
if let Err(err) = buf.entry(DirEntry {
|
||||
kind: DirentKind::Unspecified,
|
||||
name: name,
|
||||
name: &name.clone(),
|
||||
inode: 0,
|
||||
next_opaque_id: i as u64 + 1,
|
||||
}) {
|
||||
if err.errno == EINVAL && i > opaque_offset {
|
||||
// POSIX allows partial result of getdents
|
||||
break;
|
||||
} else {
|
||||
return Err(err);
|
||||
@@ -485,7 +438,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
|
||||
fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> {
|
||||
let resource_stat = match self.handles.get(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(_) | Handle::OtherScheme { .. } => Stat {
|
||||
Handle::List(_) => Stat {
|
||||
st_mode: 0o444 | syscall::MODE_DIR,
|
||||
st_uid: 0,
|
||||
st_gid: 0,
|
||||
@@ -547,9 +500,6 @@ pub fn run(
|
||||
schemes: HashMap<String, Arc<FdGuard>>,
|
||||
scheme_creation_cap: FdGuard,
|
||||
) -> ! {
|
||||
let scheme_creation_cap = scheme_creation_cap
|
||||
.to_upper()
|
||||
.expect("Failed to move scheme creation cap into upper");
|
||||
let mut state = SchemeState::new();
|
||||
let mut scheme = NamespaceScheme::new(&socket, schemes, scheme_creation_cap);
|
||||
|
||||
@@ -561,7 +511,7 @@ pub fn run(
|
||||
.socket
|
||||
.create_this_scheme_fd(0, new_id, 0, 0)
|
||||
.expect("nsmgr: failed to create namespace fd");
|
||||
let _ = redox_rt::sys::sys_call_wo(
|
||||
let _ = syscall::call_wo(
|
||||
sync_pipe.as_raw_fd(),
|
||||
&cap_fd.to_ne_bytes(),
|
||||
CallFlags::FD,
|
||||
@@ -599,6 +549,7 @@ pub fn run(
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
+24
-7
@@ -1,6 +1,7 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(abort_immediate, never_type)]
|
||||
#![allow(internal_features)]
|
||||
#![feature(core_intrinsics, str_from_raw_parts, never_type)]
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[path = "aarch64.rs"]
|
||||
@@ -38,18 +39,34 @@ use syscall::flag::MapFlags;
|
||||
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
|
||||
use core::fmt::Write;
|
||||
|
||||
struct Writer;
|
||||
// Try fd 1 first (opened in start()). If that fails, open a fresh debug handle.
|
||||
struct Writer {
|
||||
fd: usize,
|
||||
}
|
||||
|
||||
impl Write for Writer {
|
||||
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
syscall::write(1, s.as_bytes())
|
||||
.map_err(|_| core::fmt::Error)
|
||||
.map(|_| ())
|
||||
// Try writing to our fd. If it fails and we're on fd 1,
|
||||
// attempt to open a fresh debug handle.
|
||||
if libredox::call::write(self.fd, s.as_bytes()).is_ok() {
|
||||
return Ok(());
|
||||
}
|
||||
if self.fd == 1 {
|
||||
let debug_root =
|
||||
syscall::UPPER_FDTBL_TAG + syscall::data::GlobalSchemes::Debug as usize;
|
||||
if let Ok(new_fd) =
|
||||
libredox::call::openat(debug_root, "", syscall::O_WRONLY as i32, 0)
|
||||
{
|
||||
self.fd = new_fd;
|
||||
let _ = libredox::call::write(self.fd, s.as_bytes());
|
||||
}
|
||||
}
|
||||
Ok(()) // Always succeed so writeln! continues formatting
|
||||
}
|
||||
}
|
||||
|
||||
let _ = writeln!(&mut Writer, "{}", info);
|
||||
core::process::abort_immediate();
|
||||
let _ = writeln!(Writer { fd: 1 }, "{}", info);
|
||||
core::intrinsics::abort();
|
||||
}
|
||||
|
||||
const HEAP_OFF: usize = arch::USERMODE_END / 2;
|
||||
|
||||
+28
-21
@@ -46,15 +46,20 @@ enum VirtualId {
|
||||
}
|
||||
|
||||
pub fn run(write_fd: FdGuard, socket: Socket, auth: FdGuard, event: FdGuard) -> ! {
|
||||
let _ = libredox::call::write(1, b"PM:0\n");
|
||||
// TODO?
|
||||
let socket_ident = socket.inner().raw();
|
||||
let _ = libredox::call::write(1, b"PM:1\n");
|
||||
|
||||
let queue = RawEventQueue::new(event.as_raw_fd()).expect("failed to create event queue");
|
||||
let _ = libredox::call::write(1, b"PM:2\n");
|
||||
drop(event);
|
||||
let _ = libredox::call::write(1, b"PM:3\n");
|
||||
|
||||
queue
|
||||
.subscribe(socket.inner().raw(), socket_ident, EventFlags::EVENT_READ)
|
||||
.expect("failed to listen to scheme socket events");
|
||||
let _ = libredox::call::write(1, b"PM:4\n");
|
||||
|
||||
let mut scheme = ProcScheme::new(auth, &queue);
|
||||
|
||||
@@ -63,9 +68,10 @@ pub fn run(write_fd: FdGuard, socket: Socket, auth: FdGuard, event: FdGuard) ->
|
||||
let cap_fd = socket
|
||||
.create_this_scheme_fd(0, new_id, 0, 0)
|
||||
.expect("failed to issue procmgr root fd");
|
||||
let _ = libredox::call::write(1, b"PM:5\n");
|
||||
|
||||
log::debug!("process manager started");
|
||||
let _ = redox_rt::sys::sys_call_wo(
|
||||
let _ = syscall::call_wo(
|
||||
write_fd.as_raw_fd(),
|
||||
&cap_fd.to_ne_bytes(),
|
||||
CallFlags::FD,
|
||||
@@ -549,7 +555,8 @@ enum WaitpidTarget {
|
||||
struct RawEventQueue(FdGuard);
|
||||
impl RawEventQueue {
|
||||
pub fn new(cap_fd: usize) -> Result<Self> {
|
||||
redox_rt::sys::openat(cap_fd, "", O_CREAT, 0)
|
||||
libredox::call::openat(cap_fd, "", O_CREAT as i32, 0)
|
||||
.map_err(Into::into)
|
||||
.map(FdGuard::new)
|
||||
.map(Self)
|
||||
}
|
||||
@@ -725,7 +732,10 @@ impl<'a> ProcScheme<'a> {
|
||||
sig_pctl: None, // TODO
|
||||
rtqs: Vec::new(),
|
||||
}));
|
||||
if let Err(err) = new_process.borrow_mut().sync_kernel_attrs(&self.auth) {
|
||||
if let Err(err) = new_process
|
||||
.borrow_mut()
|
||||
.sync_kernel_attrs(&self.auth)
|
||||
{
|
||||
log::warn!("Failed to set kernel attrs when forking: {err}");
|
||||
}
|
||||
|
||||
@@ -1065,27 +1075,25 @@ impl<'a> ProcScheme<'a> {
|
||||
// FIXME remove this ProcCall variant
|
||||
ProcCall::Setrens => Response::ready_err(EINVAL, op),
|
||||
ProcCall::SetProcPriority => {
|
||||
let target_pid = NonZeroUsize::new(metadata[1] as usize)
|
||||
.map_or(fd_pid, |n| ProcessId(n.get()));
|
||||
let target_pid = NonZeroUsize::new(metadata[1] as usize).map_or(fd_pid, |n| ProcessId(n.get()));
|
||||
|
||||
let new_prio = metadata[2] as u32;
|
||||
|
||||
Ready(Response::new(
|
||||
self.on_setprocprio(fd_pid, target_pid, new_prio)
|
||||
.map(|()| 0),
|
||||
op,
|
||||
self.on_setprocprio(fd_pid, target_pid, new_prio).map(|()| 0),
|
||||
op
|
||||
))
|
||||
}
|
||||
},
|
||||
ProcCall::GetProcPriority => {
|
||||
let target_pid = NonZeroUsize::new(metadata[1] as usize)
|
||||
.map_or(fd_pid, |n| ProcessId(n.get()));
|
||||
|
||||
Ready(Response::new(
|
||||
self.on_getprocprio(fd_pid, target_pid)
|
||||
.map(|prio| prio as usize),
|
||||
self.on_getprocprio(fd_pid, target_pid).map(|prio| prio as usize),
|
||||
op,
|
||||
))
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
Handle::Ps(_) => Response::ready_err(EOPNOTSUPP, op),
|
||||
@@ -2541,8 +2549,8 @@ impl<'a> ProcScheme<'a> {
|
||||
|
||||
// Useful for debugging memory leaks.
|
||||
log::trace!("NEXT FD: {}", {
|
||||
let nextfd = redox_rt::sys::dup(0, &[]).unwrap();
|
||||
let _ = redox_rt::sys::close(nextfd);
|
||||
let nextfd = libredox::call::dup(0, &[]).unwrap();
|
||||
let _ = libredox::call::close(nextfd);
|
||||
nextfd
|
||||
});
|
||||
log::trace!("{} processes", self.processes.len());
|
||||
@@ -2565,12 +2573,7 @@ impl<'a> ProcScheme<'a> {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
let caller_euid = self
|
||||
.processes
|
||||
.get(&caller_pid)
|
||||
.ok_or(Error::new(ESRCH))?
|
||||
.borrow()
|
||||
.euid;
|
||||
let caller_euid = self.processes.get(&caller_pid).ok_or(Error::new(ESRCH))?.borrow().euid;
|
||||
|
||||
let target_rc = self.processes.get(&target_pid).ok_or(Error::new(ESRCH))?;
|
||||
let mut target = target_rc.borrow_mut();
|
||||
@@ -2587,7 +2590,11 @@ impl<'a> ProcScheme<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_getprocprio(&self, caller_pid: ProcessId, target_pid: ProcessId) -> Result<u32> {
|
||||
fn on_getprocprio(
|
||||
&self,
|
||||
caller_pid: ProcessId,
|
||||
target_pid: ProcessId,
|
||||
) -> Result<u32> {
|
||||
let target_rc = self.processes.get(&target_pid).ok_or(Error::new(ESRCH))?;
|
||||
Ok(target_rc.borrow().prio)
|
||||
}
|
||||
|
||||
+21
-9
@@ -2,13 +2,10 @@ use syscall::flag::MapFlags;
|
||||
|
||||
mod offsets {
|
||||
unsafe extern "C" {
|
||||
// text (R-X)
|
||||
static __text_start: u8;
|
||||
static __text_end: u8;
|
||||
// rodata (R--)
|
||||
static __rodata_start: u8;
|
||||
static __rodata_end: u8;
|
||||
// data+bss (RW-)
|
||||
static __data_start: u8;
|
||||
static __bss_end: u8;
|
||||
}
|
||||
@@ -38,42 +35,56 @@ mod offsets {
|
||||
}
|
||||
}
|
||||
|
||||
fn dbg(msg: &[u8]) {
|
||||
let _ = libredox::call::write(1, msg);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn start() -> ! {
|
||||
// Remap self, from the previous RWX
|
||||
|
||||
let (text_start, text_end) = offsets::text();
|
||||
let (rodata_start, rodata_end) = offsets::rodata();
|
||||
let (data_start, data_end) = offsets::data_and_bss();
|
||||
|
||||
// NOTE: Assuming the debug scheme root fd is always placed at this position
|
||||
let debug_fd = syscall::UPPER_FDTBL_TAG + syscall::data::GlobalSchemes::Debug as usize;
|
||||
let _ = syscall::openat_into(debug_fd, 0, "", syscall::O_RDONLY, 0); // stdin
|
||||
let _ = syscall::openat_into(debug_fd, 1, "", syscall::O_WRONLY, 0); // stdout
|
||||
let _ = syscall::openat_into(debug_fd, 2, "", syscall::O_WRONLY, 0); // stderr
|
||||
let _ = libredox::call::openat(debug_fd, "", syscall::O_RDONLY as i32, 0);
|
||||
let _ = libredox::call::openat(debug_fd, "", syscall::O_WRONLY as i32, 0);
|
||||
let _ = libredox::call::openat(debug_fd, "", syscall::O_WRONLY as i32, 0);
|
||||
|
||||
dbg(b"BS:0\n");
|
||||
|
||||
unsafe {
|
||||
let _ = syscall::mprotect(4096, 4096, MapFlags::PROT_READ | MapFlags::MAP_PRIVATE)
|
||||
.expect("mprotect failed for initfs header page");
|
||||
|
||||
dbg(b"BS:1\n");
|
||||
|
||||
let _ = syscall::mprotect(
|
||||
text_start,
|
||||
text_end - text_start,
|
||||
MapFlags::PROT_READ | MapFlags::PROT_EXEC | MapFlags::MAP_PRIVATE,
|
||||
)
|
||||
.expect("mprotect failed for .text");
|
||||
|
||||
dbg(b"BS:2\n");
|
||||
|
||||
let _ = syscall::mprotect(
|
||||
rodata_start,
|
||||
rodata_end - rodata_start,
|
||||
MapFlags::PROT_READ | MapFlags::MAP_PRIVATE,
|
||||
)
|
||||
.expect("mprotect failed for .rodata");
|
||||
|
||||
dbg(b"BS:3\n");
|
||||
|
||||
let _ = syscall::mprotect(
|
||||
data_start,
|
||||
data_end - data_start,
|
||||
MapFlags::PROT_READ | MapFlags::PROT_WRITE | MapFlags::MAP_PRIVATE,
|
||||
)
|
||||
.expect("mprotect failed for .data/.bss");
|
||||
|
||||
dbg(b"BS:4\n");
|
||||
|
||||
let _ = syscall::mprotect(
|
||||
data_end,
|
||||
crate::arch::STACK_START - data_end,
|
||||
@@ -82,5 +93,6 @@ pub unsafe extern "C" fn start() -> ! {
|
||||
.expect("mprotect failed for rest of memory");
|
||||
}
|
||||
|
||||
dbg(b"BS:5\n");
|
||||
crate::exec::main();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user