Add permissions to the filesystem, preliminary permissions to the syscalls

This commit is contained in:
Jeremy Soller 2016-10-05 14:24:08 -06:00
parent 478bc20b85
commit f4a1d06f07
19 changed files with 142 additions and 20 deletions

View file

@ -22,6 +22,10 @@ pub struct Context {
pub id: usize,
/// The ID of the parent context
pub ppid: usize,
/// The user id
pub uid: u32,
/// The group id
pub gid: u32,
/// Status of context
pub status: Status,
/// Context running or not
@ -58,6 +62,8 @@ impl Context {
Context {
id: id,
ppid: 0,
uid: 0,
gid: 0,
status: Status::Blocked,
running: false,
vfork: false,
@ -87,6 +93,9 @@ impl Context {
.to_vec()
} else if path.starts_with(b"./") {
let mut canon = cwd.clone();
if ! canon.ends_with(b"/") {
canon.push(b'/');
}
canon.extend_from_slice(&path[2..]);
canon
} else if path.starts_with(b"../") {

View file

@ -70,6 +70,7 @@
#![feature(const_fn)]
#![feature(drop_types_in_const)]
#![feature(heap_api)]
#![feature(integer_atomics)]
#![feature(question_mark)]
#![feature(never_type)]
#![feature(thread_local)]

View file

@ -1,6 +1,6 @@
use alloc::arc::Weak;
use collections::{BTreeMap, VecDeque};
use core::sync::atomic::{AtomicUsize, Ordering};
use core::sync::atomic::{AtomicUsize, AtomicU64, Ordering};
use core::{mem, usize};
use spin::{Mutex, RwLock};
@ -16,17 +16,17 @@ use syscall::scheme::Scheme;
pub struct UserInner {
pub scheme_id: AtomicUsize,
next_id: AtomicUsize,
next_id: AtomicU64,
context: Weak<RwLock<Context>>,
todo: Mutex<VecDeque<Packet>>,
done: Mutex<BTreeMap<usize, usize>>
done: Mutex<BTreeMap<u64, usize>>
}
impl UserInner {
pub fn new(context: Weak<RwLock<Context>>) -> UserInner {
UserInner {
scheme_id: AtomicUsize::new(0),
next_id: AtomicUsize::new(1),
next_id: AtomicU64::new(1),
context: context,
todo: Mutex::new(VecDeque::new()),
done: Mutex::new(BTreeMap::new())
@ -34,10 +34,20 @@ impl UserInner {
}
pub fn call(&self, a: usize, b: usize, c: usize, d: usize) -> Result<usize> {
let (pid, uid, gid) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
(context.id, context.uid, context.gid)
};
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
let packet = Packet {
id: id,
pid: pid,
uid: uid,
gid: gid,
a: a,
b: b,
c: c,

View file

@ -48,6 +48,10 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
SYS_CLONE => clone(b, stack),
SYS_YIELD => sched_yield(),
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
SYS_GETUID => getuid(),
SYS_GETGID => getgid(),
SYS_SETUID => setuid(b as u32),
SYS_SETGID => setgid(b as u32),
SYS_FEVENT => fevent(b, c),
SYS_FPATH => fpath(b, validate_slice_mut(c as *mut u8, d)?),
SYS_PHYSALLOC => physalloc(b),

View file

@ -58,6 +58,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
let ppid;
let pid;
{
let uid;
let gid;
let arch;
let vfork;
let mut kfx_option = None;
@ -78,6 +80,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
let context = context_lock.read();
ppid = context.id;
uid = context.uid;
gid = context.gid;
arch = context.arch.clone();
@ -249,6 +253,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
pid = context.id;
context.ppid = ppid;
context.uid = uid;
context.gid = gid;
context.status = context::Status::Runnable;
@ -452,6 +458,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
drop(context.stack.take());
context.grants = Arc::new(Mutex::new(Vec::new()));
// Map and copy new segments
for segment in elf.segments() {
if segment.p_type == program_header::PT_LOAD {
let mut memory = context::memory::Memory::new(
@ -488,6 +495,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
}
}
// Map heap
context.heap = Some(context::memory::Memory::new(
VirtualAddress::new(arch::USER_HEAP_OFFSET),
0,
@ -572,6 +580,13 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
unsafe { usermode(entry, sp); }
}
pub fn getgid() -> Result<usize> {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
Ok(context.gid as usize)
}
pub fn getpid() -> Result<usize> {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@ -579,6 +594,13 @@ pub fn getpid() -> Result<usize> {
Ok(context.id)
}
pub fn getuid() -> Result<usize> {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
Ok(context.uid as usize)
}
pub fn iopl(_level: usize) -> Result<usize> {
//TODO
Ok(0)
@ -676,6 +698,34 @@ pub fn sched_yield() -> Result<usize> {
Ok(0)
}
pub fn setgid(gid: u32) -> Result<usize> {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let mut context = context_lock.write();
if context.gid == 0 {
context.gid = gid;
Ok(0)
} else if context.gid == gid {
Ok(0)
} else {
Err(Error::new(EPERM))
}
}
pub fn setuid(uid: u32) -> Result<usize> {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let mut context = context_lock.write();
if context.uid == 0 {
context.uid = uid;
Ok(0)
} else if context.uid == uid {
Ok(0)
} else {
Err(Error::new(EPERM))
}
}
pub fn virttophys(virtual_address: usize) -> Result<usize> {
let active_table = unsafe { ActivePageTable::new() };
match active_table.translate(VirtualAddress::new(virtual_address)) {