Use UTF-8 for all paths

This commit is contained in:
Jeremy Soller
2021-02-14 13:45:03 -07:00
parent 8fcd375bd9
commit d331f72f2a
28 changed files with 217 additions and 193 deletions
+23 -19
View File
@@ -1,6 +1,7 @@
//! Filesystem syscalls
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::str;
use core::sync::atomic::Ordering;
use spin::RwLock;
@@ -55,7 +56,7 @@ pub fn file_op_mut_slice(a: usize, fd: FileHandle, slice: &mut [u8]) -> Result<u
}
/// Change the current working directory
pub fn chdir(path: &[u8]) -> Result<usize> {
pub fn chdir(path: &str) -> Result<usize> {
let fd = open(path, O_RDONLY | O_DIRECTORY)?;
let mut stat = Stat::default();
let stat_res = file_op_mut_slice(syscall::number::SYS_FSTAT, fd, &mut stat);
@@ -79,16 +80,17 @@ pub fn getcwd(buf: &mut [u8]) -> Result<usize> {
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let cwd = context.cwd.read();
let cwd_bytes = cwd.as_bytes();
let mut i = 0;
while i < buf.len() && i < cwd.len() {
buf[i] = cwd[i];
while i < buf.len() && i < cwd_bytes.len() {
buf[i] = cwd_bytes[i];
i += 1;
}
Ok(i)
}
/// Open syscall
pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
pub fn open(path: &str, flags: usize) -> Result<FileHandle> {
let (mut path_canon, uid, gid, scheme_ns, umask) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -103,7 +105,7 @@ pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
for _level in 0..32 { // XXX What should the limit be?
//println!(" level {} = {:?}", _level, ::core::str::from_utf8(&path_canon));
let mut parts = path_canon.splitn(2, |&b| b == b':');
let mut parts = path_canon.splitn(2, ':');
let scheme_name_opt = parts.next();
let reference_opt = parts.next();
@@ -114,7 +116,7 @@ pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
let (scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
(scheme_id, Arc::clone(&scheme))
};
let reference = reference_opt.unwrap_or(b"");
let reference = reference_opt.unwrap_or("");
let file_id = match scheme.open(reference, flags, uid, gid) {
Ok(ok) => ok,
Err(err) => if err.errno == EXDEV {
@@ -128,10 +130,12 @@ pub fn open(path: &[u8], flags: usize) -> Result<FileHandle> {
let count = res?;
let buf_str = str::from_utf8(&buf[..count]).map_err(|_| Error::new(EINVAL))?;
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
path_canon = context.canonicalize(&buf[..count]);
path_canon = context.canonicalize(buf_str);
continue;
} else {
@@ -196,7 +200,7 @@ pub fn pipe2(fds: &mut [usize], flags: usize) -> Result<usize> {
}
/// chmod syscall
pub fn chmod(path: &[u8], mode: u16) -> Result<usize> {
pub fn chmod(path: &str, mode: u16) -> Result<usize> {
let (path_canon, uid, gid, scheme_ns) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -204,7 +208,7 @@ pub fn chmod(path: &[u8], mode: u16) -> Result<usize> {
(context.canonicalize(path), context.euid, context.egid, context.ens)
};
let mut parts = path_canon.splitn(2, |&b| b == b':');
let mut parts = path_canon.splitn(2, ':');
let scheme_name_opt = parts.next();
let reference_opt = parts.next();
@@ -214,11 +218,11 @@ pub fn chmod(path: &[u8], mode: u16) -> Result<usize> {
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
Arc::clone(&scheme)
};
scheme.chmod(reference_opt.unwrap_or(b""), mode, uid, gid)
scheme.chmod(reference_opt.unwrap_or(""), mode, uid, gid)
}
/// rmdir syscall
pub fn rmdir(path: &[u8]) -> Result<usize> {
pub fn rmdir(path: &str) -> Result<usize> {
let (path_canon, uid, gid, scheme_ns) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -226,7 +230,7 @@ pub fn rmdir(path: &[u8]) -> Result<usize> {
(context.canonicalize(path), context.euid, context.egid, context.ens)
};
let mut parts = path_canon.splitn(2, |&b| b == b':');
let mut parts = path_canon.splitn(2, ':');
let scheme_name_opt = parts.next();
let reference_opt = parts.next();
@@ -236,11 +240,11 @@ pub fn rmdir(path: &[u8]) -> Result<usize> {
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
Arc::clone(&scheme)
};
scheme.rmdir(reference_opt.unwrap_or(b""), uid, gid)
scheme.rmdir(reference_opt.unwrap_or(""), uid, gid)
}
/// Unlink syscall
pub fn unlink(path: &[u8]) -> Result<usize> {
pub fn unlink(path: &str) -> Result<usize> {
let (path_canon, uid, gid, scheme_ns) = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -248,7 +252,7 @@ pub fn unlink(path: &[u8]) -> Result<usize> {
(context.canonicalize(path), context.euid, context.egid, context.ens)
};
let mut parts = path_canon.splitn(2, |&b| b == b':');
let mut parts = path_canon.splitn(2, ':');
let scheme_name_opt = parts.next();
let reference_opt = parts.next();
@@ -258,7 +262,7 @@ pub fn unlink(path: &[u8]) -> Result<usize> {
let (_scheme_id, scheme) = schemes.get_name(scheme_ns, scheme_name).ok_or(Error::new(ENODEV))?;
Arc::clone(&scheme)
};
scheme.unlink(reference_opt.unwrap_or(b""), uid, gid)
scheme.unlink(reference_opt.unwrap_or(""), uid, gid)
}
/// Close syscall
@@ -409,7 +413,7 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize) -> Result<usize> {
}
}
pub fn frename(fd: FileHandle, path: &[u8]) -> Result<usize> {
pub fn frename(fd: FileHandle, path: &str) -> Result<usize> {
let file = {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
@@ -424,7 +428,7 @@ pub fn frename(fd: FileHandle, path: &[u8]) -> Result<usize> {
(context.canonicalize(path), context.euid, context.egid, context.ens)
};
let mut parts = path_canon.splitn(2, |&b| b == b':');
let mut parts = path_canon.splitn(2, ':');
let scheme_name_opt = parts.next();
let reference_opt = parts.next();
@@ -438,7 +442,7 @@ pub fn frename(fd: FileHandle, path: &[u8]) -> Result<usize> {
let description = file.description.read();
if scheme_id == description.scheme {
scheme.frename(description.number, reference_opt.unwrap_or(b""), uid, gid)
scheme.frename(description.number, reference_opt.unwrap_or(""), uid, gid)
} else {
Err(Error::new(EXDEV))
}
+6 -6
View File
@@ -75,7 +75,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u
SYS_DUP2 => dup2(fd, FileHandle::from(c), validate_slice(d as *const u8, e)?).map(FileHandle::into),
SYS_FCNTL => fcntl(fd, c, d),
SYS_FEXEC => fexec(fd, validate_slice(c as *const [usize; 2], d)?, validate_slice(e as *const [usize; 2], f)?),
SYS_FRENAME => frename(fd, validate_slice(c as *const u8, d)?),
SYS_FRENAME => frename(fd, validate_str(c as *const u8, d)?),
SYS_FUNMAP => funmap(b, c),
SYS_FMAP_OLD => {
{
@@ -100,10 +100,10 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u
}
},
SYS_CLASS_PATH => match a {
SYS_OPEN => open(validate_slice(b as *const u8, c)?, d).map(FileHandle::into),
SYS_CHMOD => chmod(validate_slice(b as *const u8, c)?, d as u16),
SYS_RMDIR => rmdir(validate_slice(b as *const u8, c)?),
SYS_UNLINK => unlink(validate_slice(b as *const u8, c)?),
SYS_OPEN => open(validate_str(b as *const u8, c)?, d).map(FileHandle::into),
SYS_CHMOD => chmod(validate_str(b as *const u8, c)?, d as u16),
SYS_RMDIR => rmdir(validate_str(b as *const u8, c)?),
SYS_UNLINK => unlink(validate_str(b as *const u8, c)?),
_ => Err(Error::new(ENOSYS))
},
_ => match a {
@@ -145,7 +145,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u
SYS_EXIT => exit((b & 0xFF) << 8),
SYS_KILL => kill(ContextId::from(b), c),
SYS_WAITPID => waitpid(ContextId::from(b), c, WaitFlags::from_bits_truncate(d)).map(ContextId::into),
SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?),
SYS_CHDIR => chdir(validate_str(b as *const u8, c)?),
SYS_IOPL => iopl(b, stack),
SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?),
SYS_GETEGID => getegid(),
+2 -2
View File
@@ -3,7 +3,7 @@ use alloc::vec::Vec;
use crate::context;
use crate::scheme::{self, SchemeNamespace};
use crate::syscall::error::*;
use crate::syscall::validate::validate_slice;
use crate::syscall::validate::validate_str;
pub fn getegid() -> Result<usize> {
let contexts = context::contexts();
@@ -50,7 +50,7 @@ pub fn getuid() -> Result<usize> {
pub fn mkns(name_ptrs: &[[usize; 2]]) -> Result<usize> {
let mut names = Vec::new();
for name_ptr in name_ptrs {
names.push(validate_slice(name_ptr[0] as *const u8, name_ptr[1])?);
names.push(validate_str(name_ptr[0] as *const u8, name_ptr[1])?);
}
let (uid, from) = {
+5 -3
View File
@@ -7,7 +7,7 @@ use alloc::{
};
use core::alloc::{GlobalAlloc, Layout};
use core::ops::DerefMut;
use core::{intrinsics, mem};
use core::{intrinsics, mem, str};
use spin::RwLock;
use crate::context::file::FileDescriptor;
@@ -1030,9 +1030,11 @@ pub fn fexec_kernel(fd: FileHandle, args: Box<[Box<[u8]>]>, vars: Box<[Box<[u8]>
}
interp.truncate(i);
println!(" interpreter: {:?}", ::core::str::from_utf8(&interp));
let interp_str = str::from_utf8(&interp).map_err(|_| Error::new(EINVAL))?;
let interp_fd = super::fs::open(&interp, super::flag::O_RDONLY | super::flag::O_CLOEXEC)?;
println!(" interpreter: {}", interp_str);
let interp_fd = super::fs::open(interp_str, super::flag::O_RDONLY | super::flag::O_CLOEXEC)?;
let mut args_vec = Vec::from(args);
//TODO: pass file handle in auxv
+8 -1
View File
@@ -1,4 +1,4 @@
use core::{mem, slice};
use core::{mem, slice, str};
use crate::paging::{ActivePageTable, PageTableType, Page, VirtualAddress, VirtualAddressType};
use crate::paging::entry::EntryFlags;
@@ -51,3 +51,10 @@ pub fn validate_slice_mut<T>(ptr: *mut T, len: usize) -> Result<&'static mut [T]
Ok(unsafe { slice::from_raw_parts_mut(ptr, len) })
}
}
/// Convert a pointer and length to str, if valid
//TODO: Mark unsafe
pub fn validate_str(ptr: *const u8, len: usize) -> Result<&'static str> {
let slice = validate_slice(ptr, len)?;
str::from_utf8(slice).map_err(|_| Error::new(EINVAL))
}