WIP: Replace fexec with exec.
This commit is contained in:
17
src/call.rs
17
src/call.rs
@@ -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
|
||||
|
||||
30
src/data.rs
30
src/data.rs
@@ -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>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user