Create example userspace scheme. Remove kernel duplication of syscalls, use syscall crate instead

This commit is contained in:
Jeremy Soller 2016-09-20 16:23:28 -06:00
parent 941fc0b494
commit f60661820d
25 changed files with 374 additions and 414 deletions

View file

@ -1,5 +1,6 @@
use core::{fmt, result};
#[derive(Eq, PartialEq)]
pub struct Error {
pub errno: isize,
}

View file

@ -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)]

28
syscall/src/number.rs Normal file
View file

@ -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;

View file

@ -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<usize> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn mkdir(&self, path: &[u8], mode: usize) -> Result<usize> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn rmdir(&self, path: &[u8]) -> Result<usize> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn stat(&self, path: &[u8], stat: &mut Stat) -> Result<usize> {
Err(Error::new(ENOENT))
}
#[allow(unused_variables)]
fn unlink(&self, path: &[u8]) -> Result<usize> {
Err(Error::new(ENOENT))
}
/* Resource operations */
#[allow(unused_variables)]
fn dup(&self, old_id: usize) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn fsync(&self, id: usize) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn ftruncate(&self, id: usize, len: usize) -> Result<usize> {
Err(Error::new(EBADF))
}
#[allow(unused_variables)]
fn close(&self, id: usize) -> Result<usize> {
Err(Error::new(EBADF))
}
}