diff --git a/Makefile b/Makefile index 702004f..70307a1 100644 --- a/Makefile +++ b/Makefile @@ -276,15 +276,18 @@ $(BUILD)/filesystem.bin: \ extrautils \ schemes \ filesystem/bin/getty \ + filesystem/bin/id \ filesystem/bin/ion \ filesystem/bin/login \ filesystem/bin/smith rm -rf $@ $(BUILD)/filesystem/ - echo exit | cargo run --manifest-path schemes/redoxfs/Cargo.toml --bin redoxfs-utility $@ + echo exit | cargo run --manifest-path schemes/redoxfs/Cargo.toml --bin redoxfs-utility $@ 8 mkdir -p $(BUILD)/filesystem/ cargo run --manifest-path schemes/redoxfs/Cargo.toml --bin redoxfs-fuse $@ $(BUILD)/filesystem/ & sleep 2 -cp -RL filesystem/* $(BUILD)/filesystem/ + -chown -R 0:0 $(BUILD)/filesystem/ + -chown -R 1000:1000 $(BUILD)/filesystem/home/user/ sync -fusermount -u $(BUILD)/filesystem/ rm -rf $(BUILD)/filesystem/ diff --git a/drivers/vesad/src/main.rs b/drivers/vesad/src/main.rs index 74c17f9..5deb03e 100644 --- a/drivers/vesad/src/main.rs +++ b/drivers/vesad/src/main.rs @@ -258,6 +258,9 @@ fn main() { if ! scheme.input.borrow().is_empty() && *scheme.requested.borrow() & EVENT_READ == EVENT_READ { let event_packet = Packet { id: 0, + pid: 0, + uid: 0, + gid: 0, a: syscall::number::SYS_FEVENT, b: 0, c: EVENT_READ, diff --git a/kernel/context/context.rs b/kernel/context/context.rs index 8f63755..512c66e 100644 --- a/kernel/context/context.rs +++ b/kernel/context/context.rs @@ -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"../") { diff --git a/kernel/lib.rs b/kernel/lib.rs index fee417c..f77da77 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -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)] diff --git a/kernel/scheme/user.rs b/kernel/scheme/user.rs index dd415cc..96ba87e 100644 --- a/kernel/scheme/user.rs +++ b/kernel/scheme/user.rs @@ -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>, todo: Mutex>, - done: Mutex> + done: Mutex> } impl UserInner { pub fn new(context: Weak>) -> 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 { + 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, diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index d799da0..3c2523f 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -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), diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index d6da9f2..e8d001f 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -58,6 +58,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result { 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 { 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 { 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 { 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 { } } + // 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 { unsafe { usermode(entry, sp); } } +pub fn getgid() -> Result { + 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 { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; @@ -579,6 +594,13 @@ pub fn getpid() -> Result { Ok(context.id) } +pub fn getuid() -> Result { + 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 { //TODO Ok(0) @@ -676,6 +698,34 @@ pub fn sched_yield() -> Result { Ok(0) } +pub fn setgid(gid: u32) -> Result { + 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 { + 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 { let active_table = unsafe { ActivePageTable::new() }; match active_table.translate(VirtualAddress::new(virtual_address)) { diff --git a/libstd b/libstd index 452e1c1..60c282e 160000 --- a/libstd +++ b/libstd @@ -1 +1 @@ -Subproject commit 452e1c13eef2faeb4252639da692fa8c335d35dd +Subproject commit 60c282e9b09cc37251d0229108398e7d7add99b9 diff --git a/programs/coreutils b/programs/coreutils index 648a0d1..fe104e7 160000 --- a/programs/coreutils +++ b/programs/coreutils @@ -1 +1 @@ -Subproject commit 648a0d119aaed8f4cf8c856e05e47da421c4074a +Subproject commit fe104e72ea1d756556e0d6d98158713f6c3a8a38 diff --git a/programs/extrautils b/programs/extrautils index 6f0ef49..d6c122a 160000 --- a/programs/extrautils +++ b/programs/extrautils @@ -1 +1 @@ -Subproject commit 6f0ef493c9f48f7b0c8dfe7c2a9a029f68fdda19 +Subproject commit d6c122a94cd760819f139f2af6ea22e4f4b17151 diff --git a/programs/getty/src/main.rs b/programs/getty/src/main.rs index 79ce665..ec4f361 100644 --- a/programs/getty/src/main.rs +++ b/programs/getty/src/main.rs @@ -2,8 +2,7 @@ extern crate syscall; -use std::fs::File; -use std::io::{Read, Write}; +use std::io::Write; use std::process::Command; use std::{env, io, str, thread}; diff --git a/programs/id/Cargo.toml b/programs/id/Cargo.toml new file mode 100644 index 0000000..d9dedcd --- /dev/null +++ b/programs/id/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "id" +version = "0.1.0" + +[dependencies] +syscall = { path = "../../syscall/" } diff --git a/programs/id/src/main.rs b/programs/id/src/main.rs new file mode 100644 index 0000000..4e4d41b --- /dev/null +++ b/programs/id/src/main.rs @@ -0,0 +1,11 @@ +#![feature(question_mark)] + +extern crate syscall; + +use std::env; + +pub fn main() { + let uid = syscall::getuid().expect("id: failed to get UID"); + let gid = syscall::getgid().expect("id: failed to get GID"); + println!("uid={}({}) gid={}({})", uid, env::var("USER").unwrap_or(String::new()), gid, ""); +} diff --git a/programs/login/src/main.rs b/programs/login/src/main.rs index c611835..6bb550f 100644 --- a/programs/login/src/main.rs +++ b/programs/login/src/main.rs @@ -7,15 +7,15 @@ use octavo::octavo_digest::Digest; use octavo::octavo_digest::sha3::Sha512; use std::fs::File; use std::io::{Read, Write}; -use std::process::Command; -use std::{env, io, str, thread}; +use std::process::{Command, CommandExt}; +use std::{io, str}; use termion::input::TermRead; pub struct Passwd<'a> { user: &'a str, hash: &'a str, - uid: usize, - gid: usize, + uid: u32, + gid: u32, name: &'a str, home: &'a str, shell: &'a str @@ -27,8 +27,8 @@ impl<'a> Passwd<'a> { let user = parts.next().ok_or(())?; let hash = parts.next().ok_or(())?; - let uid = parts.next().ok_or(())?.parse::().or(Err(()))?; - let gid = parts.next().ok_or(())?.parse::().or(Err(()))?; + let uid = parts.next().ok_or(())?.parse::().or(Err(()))?; + let gid = parts.next().ok_or(())?.parse::().or(Err(()))?; let name = parts.next().ok_or(())?; let home = parts.next().ok_or(())?; let shell = parts.next().ok_or(())?; @@ -118,7 +118,10 @@ pub fn main() { let mut command = Command::new(passwd.shell); - env::set_current_dir(passwd.home).unwrap(); + command.uid(passwd.uid); + command.gid(passwd.gid); + + command.current_dir(passwd.home); command.env("USER", &user); command.env("HOME", passwd.home); diff --git a/rust b/rust index f1f40f8..a5dac7a 160000 --- a/rust +++ b/rust @@ -1 +1 @@ -Subproject commit f1f40f850e2546c2c187514e3d61d17544ba433f +Subproject commit a5dac7a2af3ee444817eb7bfbba3539be8c06cf1 diff --git a/schemes/redoxfs b/schemes/redoxfs index 1488d1e..c06edb2 160000 --- a/schemes/redoxfs +++ b/schemes/redoxfs @@ -1 +1 @@ -Subproject commit 1488d1ef5661496aff695f2e1bf67997d4654329 +Subproject commit c06edb232b48024a7a8e468dd5316d5b28a3eac9 diff --git a/syscall/src/data.rs b/syscall/src/data.rs index 7200006..a92a199 100644 --- a/syscall/src/data.rs +++ b/syscall/src/data.rs @@ -28,7 +28,10 @@ impl DerefMut for Event { #[derive(Copy, Clone, Debug, Default)] #[repr(packed)] pub struct Packet { - pub id: usize, + pub id: u64, + pub pid: usize, + pub uid: u32, + pub gid: u32, pub a: usize, pub b: usize, pub c: usize, diff --git a/syscall/src/lib.rs b/syscall/src/lib.rs index 15ac101..c616a81 100644 --- a/syscall/src/lib.rs +++ b/syscall/src/lib.rs @@ -86,10 +86,18 @@ pub fn getcwd(buf: &mut [u8]) -> Result { unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) } } +pub fn getgid() -> Result { + unsafe { syscall0(SYS_GETGID) } +} + pub fn getpid() -> Result { unsafe { syscall0(SYS_GETPID) } } +pub fn getuid() -> Result { + unsafe { syscall0(SYS_GETUID) } +} + pub unsafe fn iopl(level: usize) -> Result { syscall1(SYS_IOPL, level) } @@ -142,6 +150,14 @@ pub fn rmdir(path: &str) -> Result { unsafe { syscall2(SYS_RMDIR, path.as_ptr() as usize, path.len()) } } +pub fn setgid(gid: usize) -> Result { + unsafe { syscall1(SYS_SETGID, gid) } +} + +pub fn setuid(uid: usize) -> Result { + unsafe { syscall1(SYS_SETUID, uid) } +} + pub fn unlink(path: &str) -> Result { unsafe { syscall2(SYS_UNLINK, path.as_ptr() as usize, path.len()) } } diff --git a/syscall/src/number.rs b/syscall/src/number.rs index b0d41c0..718f75f 100644 --- a/syscall/src/number.rs +++ b/syscall/src/number.rs @@ -13,7 +13,9 @@ 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_GETGID: usize = 200; pub const SYS_GETPID: usize = 20; +pub const SYS_GETUID: usize = 199; pub const SYS_IOPL: usize = 110; pub const SYS_LINK: usize = 9; pub const SYS_LSEEK: usize = 19; @@ -28,6 +30,8 @@ pub const SYS_VIRTTOPHYS: usize = 949; pub const SYS_PIPE2: usize = 331; pub const SYS_READ: usize = 3; pub const SYS_RMDIR: usize = 84; +pub const SYS_SETGID: usize = 214; +pub const SYS_SETUID: usize = 213; pub const SYS_UNLINK: usize = 10; pub const SYS_WAITPID: usize = 7; pub const SYS_WRITE: usize = 4;