From a5cfb8f363e600772b0fcbfee14e7bf0a596ce2b Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 20 Sep 2016 16:23:28 -0600 Subject: [PATCH] Create example userspace scheme. Remove kernel duplication of syscalls, use syscall crate instead --- src/error.rs | 1 + src/lib.rs | 111 ++++++++++++++++++++------------------------------ src/number.rs | 28 +++++++++++++ src/scheme.rs | 98 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 172 insertions(+), 66 deletions(-) create mode 100644 src/number.rs diff --git a/src/error.rs b/src/error.rs index 9af8f4a..5481f9f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,6 @@ use core::{fmt, result}; +#[derive(Eq, PartialEq)] pub struct Error { pub errno: isize, } diff --git a/src/lib.rs b/src/lib.rs index 51032bb..e55ed44 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ pub use self::arch::*; pub use self::error::*; +pub use self::number::*; pub use self::scheme::*; #[cfg(target_arch = "x86")] @@ -13,74 +14,52 @@ mod arch; #[path="x86_64.rs"] mod arch; -mod error; +pub mod error; -mod scheme; +pub mod number; -pub const SYS_BRK: usize = 45; -pub const SYS_CHDIR: usize = 12; -pub const SYS_CLONE: usize = 120; - pub const CLONE_VM: usize = 0x100; - pub const CLONE_FS: usize = 0x200; - pub const CLONE_FILES: usize = 0x400; - pub const CLONE_VFORK: usize = 0x4000; - /// Mark this clone as supervised. - /// - /// This means that the process can run in supervised mode, even not being connected to - /// a supervisor yet. In other words, the parent can later on supervise the process and handle - /// the potential blocking syscall. - /// - /// This is an important security measure, since otherwise the process would be able to fork it - /// self right after starting, making supervising it impossible. - pub const CLONE_SUPERVISE: usize = 0x400000; -pub const SYS_CLOSE: usize = 6; -pub const SYS_CLOCK_GETTIME: usize = 265; - pub const CLOCK_REALTIME: usize = 1; - pub const CLOCK_MONOTONIC: usize = 4; -pub const SYS_DUP: usize = 41; -pub const SYS_EXECVE: usize = 11; -pub const SYS_EXIT: usize = 1; -pub const SYS_FPATH: usize = 928; -pub const SYS_FSTAT: usize = 28; - pub const MODE_DIR: u16 = 0x4000; - pub const MODE_FILE: u16 = 0x8000; - pub const MODE_ALL: u16 = MODE_DIR | MODE_FILE; -pub const SYS_FSYNC: usize = 118; -pub const SYS_FTRUNCATE: usize = 93; -pub const SYS_FUTEX: usize = 240; - pub const FUTEX_WAIT: usize = 0; - pub const FUTEX_WAKE: usize = 1; - pub const FUTEX_REQUEUE: usize = 2; -pub const SYS_GETCWD: usize = 183; -pub const SYS_GETPID: usize = 20; -pub const SYS_IOPL: usize = 110; -pub const SYS_LINK: usize = 9; -pub const SYS_LSEEK: usize = 19; - pub const SEEK_SET: usize = 0; - pub const SEEK_CUR: usize = 1; - pub const SEEK_END: usize = 2; -pub const SYS_MKDIR: usize = 39; -pub const SYS_NANOSLEEP: usize = 162; -pub const SYS_OPEN: usize = 5; - pub const O_RDONLY: usize = 0; - pub const O_WRONLY: usize = 1; - pub const O_RDWR: usize = 2; - pub const O_NONBLOCK: usize = 4; - pub const O_APPEND: usize = 8; - pub const O_SHLOCK: usize = 0x10; - pub const O_EXLOCK: usize = 0x20; - pub const O_ASYNC: usize = 0x40; - pub const O_FSYNC: usize = 0x80; - pub const O_CREAT: usize = 0x200; - pub const O_TRUNC: usize = 0x400; - pub const O_EXCL: usize = 0x800; -pub const SYS_PIPE2: usize = 331; -pub const SYS_READ: usize = 3; -pub const SYS_RMDIR: usize = 84; -pub const SYS_UNLINK: usize = 10; -pub const SYS_WAITPID: usize = 7; -pub const SYS_WRITE: usize = 4; -pub const SYS_YIELD: usize = 158; +pub mod scheme; + +pub const CLONE_VM: usize = 0x100; +pub const CLONE_FS: usize = 0x200; +pub const CLONE_FILES: usize = 0x400; +pub const CLONE_VFORK: usize = 0x4000; +/// Mark this clone as supervised. +/// +/// This means that the process can run in supervised mode, even not being connected to +/// a supervisor yet. In other words, the parent can later on supervise the process and handle +/// the potential blocking syscall. +/// +/// This is an important security measure, since otherwise the process would be able to fork it +/// self right after starting, making supervising it impossible. +pub const CLONE_SUPERVISE: usize = 0x400000; +pub const CLOCK_REALTIME: usize = 1; +pub const CLOCK_MONOTONIC: usize = 4; + +pub const MODE_DIR: u16 = 0x4000; +pub const MODE_FILE: u16 = 0x8000; +pub const MODE_ALL: u16 = MODE_DIR | MODE_FILE; + +pub const FUTEX_WAIT: usize = 0; +pub const FUTEX_WAKE: usize = 1; +pub const FUTEX_REQUEUE: usize = 2; + +pub const SEEK_SET: usize = 0; +pub const SEEK_CUR: usize = 1; +pub const SEEK_END: usize = 2; + +pub const O_RDONLY: usize = 0; +pub const O_WRONLY: usize = 1; +pub const O_RDWR: usize = 2; +pub const O_NONBLOCK: usize = 4; +pub const O_APPEND: usize = 8; +pub const O_SHLOCK: usize = 0x10; +pub const O_EXLOCK: usize = 0x20; +pub const O_ASYNC: usize = 0x40; +pub const O_FSYNC: usize = 0x80; +pub const O_CREAT: usize = 0x200; +pub const O_TRUNC: usize = 0x400; +pub const O_EXCL: usize = 0x800; #[derive(Copy, Clone, Debug, Default)] #[repr(packed)] diff --git a/src/number.rs b/src/number.rs new file mode 100644 index 0000000..e65c37f --- /dev/null +++ b/src/number.rs @@ -0,0 +1,28 @@ +pub const SYS_BRK: usize = 45; +pub const SYS_CHDIR: usize = 12; +pub const SYS_CLONE: usize = 120; +pub const SYS_CLOSE: usize = 6; +pub const SYS_CLOCK_GETTIME: usize = 265; +pub const SYS_DUP: usize = 41; +pub const SYS_EXECVE: usize = 11; +pub const SYS_EXIT: usize = 1; +pub const SYS_FPATH: usize = 928; +pub const SYS_FSTAT: usize = 28; +pub const SYS_FSYNC: usize = 118; +pub const SYS_FTRUNCATE: usize = 93; +pub const SYS_FUTEX: usize = 240; +pub const SYS_GETCWD: usize = 183; +pub const SYS_GETPID: usize = 20; +pub const SYS_IOPL: usize = 110; +pub const SYS_LINK: usize = 9; +pub const SYS_LSEEK: usize = 19; +pub const SYS_MKDIR: usize = 39; +pub const SYS_NANOSLEEP: usize = 162; +pub const SYS_OPEN: usize = 5; +pub const SYS_PIPE2: usize = 331; +pub const SYS_READ: usize = 3; +pub const SYS_RMDIR: usize = 84; +pub const SYS_UNLINK: usize = 10; +pub const SYS_WAITPID: usize = 7; +pub const SYS_WRITE: usize = 4; +pub const SYS_YIELD: usize = 158; diff --git a/src/scheme.rs b/src/scheme.rs index 756fc26..40405c4 100644 --- a/src/scheme.rs +++ b/src/scheme.rs @@ -1,6 +1,8 @@ use core::ops::{Deref, DerefMut}; use core::{mem, slice}; +use super::*; + #[derive(Copy, Clone, Debug, Default)] #[repr(packed)] pub struct Packet { @@ -27,3 +29,99 @@ impl DerefMut for Packet { } } } + +pub trait Scheme { + fn handle(&self, packet: &mut Packet) { + packet.a = Error::mux(match packet.a { + SYS_OPEN => self.open(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d), + SYS_MKDIR => self.mkdir(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }, packet.d), + SYS_RMDIR => self.rmdir(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }), + SYS_UNLINK => self.unlink(unsafe { slice::from_raw_parts(packet.b as *const u8, packet.c) }), + + SYS_DUP => self.dup(packet.b), + SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), + SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }), + SYS_LSEEK => self.seek(packet.b, packet.c, packet.d), + SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }), + SYS_FSTAT => self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) }), + SYS_FSYNC => self.fsync(packet.b), + SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c), + SYS_CLOSE => self.close(packet.b), + + _ => Err(Error::new(ENOSYS)) + }); + } + + /* Scheme operations */ + + #[allow(unused_variables)] + fn open(&self, path: &[u8], flags: usize) -> Result { + Err(Error::new(ENOENT)) + } + + #[allow(unused_variables)] + fn mkdir(&self, path: &[u8], mode: usize) -> Result { + Err(Error::new(ENOENT)) + } + + #[allow(unused_variables)] + fn rmdir(&self, path: &[u8]) -> Result { + Err(Error::new(ENOENT)) + } + + #[allow(unused_variables)] + fn stat(&self, path: &[u8], stat: &mut Stat) -> Result { + Err(Error::new(ENOENT)) + } + + #[allow(unused_variables)] + fn unlink(&self, path: &[u8]) -> Result { + Err(Error::new(ENOENT)) + } + + /* Resource operations */ + #[allow(unused_variables)] + fn dup(&self, old_id: usize) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn read(&self, id: usize, buf: &mut [u8]) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn write(&self, id: usize, buf: &[u8]) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn seek(&self, id: usize, pos: usize, whence: usize) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn fpath(&self, id: usize, buf: &mut [u8]) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn fstat(&self, id: usize, stat: &mut Stat) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn fsync(&self, id: usize) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn ftruncate(&self, id: usize, len: usize) -> Result { + Err(Error::new(EBADF)) + } + + #[allow(unused_variables)] + fn close(&self, id: usize) -> Result { + Err(Error::new(EBADF)) + } +}