Files
RedBear-OS/src/syscall/debug.rs
T
Jeremy Soller 788526a3b3 Bare-bones ptracing functionality
Since even a very basic ptrace can be nice to have, I thought I would split
the, perhaps rather big, ptrace project up in multiple PRs to make as few
changes as necessary in each. This PR contains the initial registry modifying
bits and only a very basic security measure. Letting this out to the community
should be good for spotting bugs and maybe getting some hype ;)
2019-07-02 07:38:26 -06:00

309 lines
7.7 KiB
Rust

use core::{ascii, mem};
use alloc::string::String;
use alloc::vec::Vec;
use super::data::{Map, Stat, TimeSpec};
use super::flag::*;
use super::number::*;
use super::validate::*;
struct ByteStr<'a>(&'a[u8]);
impl<'a> ::core::fmt::Debug for ByteStr<'a> {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "\"")?;
for i in self.0 {
for ch in ascii::escape_default(*i) {
write!(f, "{}", ch as char)?;
}
}
write!(f, "\"")?;
Ok(())
}
}
pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> String {
match a {
SYS_OPEN => format!(
"open({:?}, {:#X})",
validate_slice(b as *const u8, c).map(ByteStr),
d
),
SYS_CHMOD => format!(
"chmod({:?}, {:#o})",
validate_slice(b as *const u8, c).map(ByteStr),
d
),
SYS_RMDIR => format!(
"rmdir({:?})",
validate_slice(b as *const u8, c).map(ByteStr)
),
SYS_UNLINK => format!(
"unlink({:?})",
validate_slice(b as *const u8, c).map(ByteStr)
),
SYS_CLOSE => format!(
"close({})", b
),
SYS_DUP => format!(
"dup({}, {:?})",
b,
validate_slice(c as *const u8, d).map(ByteStr)
),
SYS_DUP2 => format!(
"dup2({}, {}, {:?})",
b,
c,
validate_slice(d as *const u8, e).map(ByteStr)
),
SYS_READ => format!(
"read({}, {:#X}, {})",
b,
c,
d
),
SYS_WRITE => format!(
"write({}, {:#X}, {})",
b,
c,
d
),
SYS_LSEEK => format!(
"lseek({}, {}, {} ({}))",
b,
c as isize,
match d {
SEEK_SET => "SEEK_SET",
SEEK_CUR => "SEEK_CUR",
SEEK_END => "SEEK_END",
_ => "UNKNOWN"
},
d
),
SYS_FCNTL => format!(
"fcntl({}, {} ({}), {:#X})",
b,
match c {
F_DUPFD => "F_DUPFD",
F_GETFD => "F_GETFD",
F_SETFD => "F_SETFD",
F_SETFL => "F_SETFL",
F_GETFL => "F_GETFL",
_ => "UNKNOWN"
},
c,
d
),
SYS_FMAP => format!(
"fmap({}, {:?})",
b,
validate_slice(
c as *const Map,
d/mem::size_of::<Map>()
),
),
SYS_FUNMAP => format!(
"funmap({:#X})",
b
),
SYS_FPATH => format!(
"fpath({}, {:#X}, {})",
b,
c,
d
),
SYS_FSTAT => format!(
"fstat({}, {:?})",
b,
validate_slice(
c as *const Stat,
d/mem::size_of::<Stat>()
),
),
SYS_FSTATVFS => format!(
"fstatvfs({}, {:#X}, {})",
b,
c,
d
),
SYS_FSYNC => format!(
"fsync({})",
b
),
SYS_FTRUNCATE => format!(
"ftruncate({}, {})",
b,
c
),
SYS_BRK => format!(
"brk({:#X})",
b
),
SYS_CHDIR => format!(
"chdir({:?})",
validate_slice(b as *const u8, c).map(ByteStr)
),
SYS_CLOCK_GETTIME => format!(
"clock_gettime({}, {:?})",
b,
validate_slice_mut(c as *mut TimeSpec, 1)
),
SYS_CLONE => format!(
"clone({})",
b
),
SYS_EXIT => format!(
"exit({})",
b
),
//TODO: Cleanup, do not allocate
SYS_FEXEC => format!(
"fexec({}, {:?}, {:?})",
b,
validate_slice(
c as *const [usize; 2],
d
).map(|slice| {
slice.iter().map(|a|
validate_slice(a[0] as *const u8, a[1]).ok()
.and_then(|s| ::core::str::from_utf8(s).ok())
).collect::<Vec<Option<&str>>>()
}),
validate_slice(
e as *const [usize; 2],
f
).map(|slice| {
slice.iter().map(|a|
validate_slice(a[0] as *const u8, a[1]).ok()
.and_then(|s| ::core::str::from_utf8(s).ok())
).collect::<Vec<Option<&str>>>()
})
),
SYS_FUTEX => format!(
"futex({:#X} [{:?}], {}, {}, {}, {})",
b,
validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0]),
c,
d,
e,
f
),
SYS_GETCWD => format!(
"getcwd({:#X}, {})",
b,
c
),
SYS_GETEGID => format!("getegid()"),
SYS_GETENS => format!("getens()"),
SYS_GETEUID => format!("geteuid()"),
SYS_GETGID => format!("getgid()"),
SYS_GETNS => format!("getns()"),
SYS_GETPID => format!("getpid()"),
SYS_GETUID => format!("getuid()"),
SYS_IOPL => format!(
"iopl({})",
b
),
SYS_KILL => format!(
"kill({}, {})",
b,
c
),
SYS_SIGRETURN => format!("sigreturn()"),
SYS_SIGACTION => format!(
"sigaction({}, {:#X}, {:#X}, {:#X})",
b,
c,
d,
e
),
SYS_SIGPROCMASK => format!(
"sigprocmask({}, {:?}, {:?})",
b,
validate_slice(c as *const [u64; 2], 1),
validate_slice(d as *const [u64; 2], 1)
),
SYS_MKNS => format!(
"mkns({:?})",
validate_slice(b as *const [usize; 2], c)
),
SYS_MPROTECT => format!(
"mprotect({:#X}, {}, {:#X})",
b,
c,
d
),
SYS_NANOSLEEP => format!(
"nanosleep({:?}, ({}, {}))",
validate_slice(b as *const TimeSpec, 1),
c,
d
),
SYS_PHYSALLOC => format!(
"physalloc({})",
b
),
SYS_PHYSFREE => format!(
"physfree({:#X}, {})",
b,
c
),
SYS_PHYSMAP => format!(
"physmap({:#X}, {}, {:#X})",
b,
c,
d
),
SYS_PHYSUNMAP => format!(
"physunmap({:#X})",
b
),
SYS_VIRTTOPHYS => format!(
"virttophys({:#X})",
b
),
SYS_PIPE2 => format!(
"pipe2({:?}, {})",
validate_slice_mut(b as *mut usize, 2),
c
),
SYS_SETREGID => format!(
"setregid({}, {})",
b,
c
),
SYS_SETRENS => format!(
"setrens({}, {})",
b,
c
),
SYS_SETREUID => format!(
"setreuid({}, {})",
b,
c
),
SYS_UMASK => format!(
"umask({:#o}",
b
),
SYS_WAITPID => format!(
"waitpid({}, {:#X}, {})",
b,
c,
d
),
SYS_YIELD => format!("yield()"),
_ => format!(
"UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X})",
a, a,
b,
c,
d,
e,
f
)
}
}