WIP: Replace fexec with exec.

This commit is contained in:
4lDO2
2022-01-02 11:57:34 +01:00
parent 0c98fbd162
commit 6d132345ee
3 changed files with 44 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
use super::arch::*;
use super::data::{Map, SigAction, Stat, StatVfs, TimeSpec};
use super::data::{ExecMemRange, Map, SigAction, Stat, StatVfs, TimeSpec};
use super::error::Result;
use super::flag::*;
use super::number::*;
@@ -85,9 +85,18 @@ pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result<usize> {
unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
}
/// Replace the current process with a new executable
pub fn fexec(fd: usize, args: &[[usize; 2]], vars: &[[usize; 2]]) -> Result<usize> {
unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(), vars.as_ptr() as usize, vars.len()) }
// TODO: Support specifying FDs to keep/close (for FDs not included in that list, it would take
// into account O_CLOEXEC).
// TODO: Allow setting all registers of the target process?
/// Replace the current process with a new executable, allowing the user to specify memory ranges
/// to either keep, move, or add. It will then jump to [`instruction_ptr`] in the new process
/// memory specified by the range map, with the stack pointer set accordingly. This syscall does
/// not support setuid/setgid; instead, privilege escalation must be done by a higher-privileged
/// process performing these actions via ptrace.
// TODO: never type
pub fn exec(memranges: &[ExecMemRange], instruction_ptr: usize, stack_ptr: usize) -> Result<core::convert::Infallible> {
unsafe { syscall4(SYS_EXEC, memranges.as_ptr() as usize, memranges.len(), instruction_ptr, stack_ptr)?; }
panic!("SYS_EXEC should only return in case of an error");
}
/// Map a file into memory, but with the ability to set the address to map into, either as a hint

View File

@@ -295,3 +295,33 @@ macro_rules! ptrace_event {
}
}
}
#[repr(C)]
pub struct ExecMemRange {
/// The address where the range is intended to be.
pub address: usize,
/// The size of the memory range.
pub size: usize,
/// Flags describing permissions (i.e. R/W/X)
pub flags: MapFlags,
/// If this equals [`address`], the range is kept untouched although flags can change, and the
/// range can be shortened or partly zeroed. If it is different, it will move `[old_address,
/// old_address+size)` to `[address, address+size]`.
pub old_address: usize,
}
impl Deref for ExecMemRange {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe {
slice::from_raw_parts(self as *const ExecMemRange as *const u8, mem::size_of::<ExecMemRange>())
}
}
}
impl DerefMut for ExecMemRange {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self as *mut ExecMemRange as *mut u8, mem::size_of::<ExecMemRange>())
}
}
}

View File

@@ -26,7 +26,6 @@ pub const SYS_FCHMOD: usize = SYS_CLASS_FILE | 94;
pub const SYS_FCHOWN: usize = SYS_CLASS_FILE | 207;
pub const SYS_FCNTL: usize = SYS_CLASS_FILE | 55;
pub const SYS_FEVENT: usize = SYS_CLASS_FILE | 927;
pub const SYS_FEXEC: usize = SYS_CLASS_FILE | 11;
pub const SYS_FMAP_OLD: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 90;
pub const SYS_FMAP: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 900;
pub const SYS_FUNMAP_OLD: usize = SYS_CLASS_FILE | 91;
@@ -39,6 +38,7 @@ pub const SYS_FSYNC: usize = SYS_CLASS_FILE | 118;
pub const SYS_FTRUNCATE: usize = SYS_CLASS_FILE | 93;
pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320;
pub const SYS_EXEC: usize = 101;
pub const SYS_CHDIR: usize = 12;
pub const SYS_CLOCK_GETTIME: usize = 265;
pub const SYS_CLONE: usize = 120;