From 21cd9e057e98c5cbce84dc86a9dd17ce70d55e9a Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:18:05 +0200 Subject: [PATCH 01/28] meta: Force SMAP to be available, if qemu can provide it. Signed-off-by: Dennis Bonke --- aero.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aero.py b/aero.py index 4fef1ad123c..f4b1d63b9f4 100755 --- a/aero.py +++ b/aero.py @@ -470,11 +470,11 @@ def run_in_emulator(args, iso_path): print("Running with KVM acceleration enabled") if platform.system() == 'Darwin': - qemu_args += ['-accel', 'hvf', '-cpu', 'qemu64,+la57' if args.la57 else 'qemu64'] + qemu_args += ['-accel', 'hvf', '-cpu', 'qemu64,+la57,+smap' if args.la57 else 'qemu64,+smap'] else: - qemu_args += ['-enable-kvm', '-cpu', 'host,+la57' if args.la57 else 'host'] + qemu_args += ['-enable-kvm', '-cpu', 'host,+la57,+smap' if args.la57 else 'host,+smap'] else: - qemu_args += ["-cpu", "qemu64,+la57" if args.la57 else "qemu64"] + qemu_args += ["-cpu", "qemu64,+la57,+smap" if args.la57 else "qemu64,+smap"] run_command(['qemu-system-x86_64', *qemu_args]) From c48541354b926b8bcdbfaae15c3e8c1cc4b3d140 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:19:20 +0200 Subject: [PATCH 02/28] arch: Add utility functions for SMAP Signed-off-by: Dennis Bonke --- .../src/arch/x86_64/controlregs.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/aero_kernel/src/arch/x86_64/controlregs.rs b/src/aero_kernel/src/arch/x86_64/controlregs.rs index d8663b1bd86..5c3911f638d 100644 --- a/src/aero_kernel/src/arch/x86_64/controlregs.rs +++ b/src/aero_kernel/src/arch/x86_64/controlregs.rs @@ -17,6 +17,8 @@ * along with Aero. If not, see . */ +use core::sync::atomic::{AtomicUsize, Ordering}; + use crate::mem::paging::{PhysAddr, PhysFrame, VirtAddr}; bitflags::bitflags! { @@ -273,3 +275,34 @@ pub fn read_cr2() -> VirtAddr { VirtAddr::new(value) } } + +/// Returns true if Supervisor Mode Access Prevention (SMAP) is supported by the CPU and is enabled in Cr4. +#[inline] +pub fn smap_enabled() -> bool { + read_cr4().contains(Cr4Flags::SUPERVISOR_MODE_ACCESS_PREVENTION) +} + +#[inline] +pub fn with_userspace_access(f: F) -> R +where + F: FnOnce() -> R, +{ + static REF_COUNT: AtomicUsize = AtomicUsize::new(0); + if smap_enabled() { + unsafe { + asm!("stac"); + } + REF_COUNT.fetch_add(1, Ordering::Acquire); + }; + let r = f(); + if smap_enabled() { + REF_COUNT.fetch_sub(1, Ordering::Release); + + if REF_COUNT.load(Ordering::Relaxed) == 0 { + unsafe { + asm!("clac"); + } + } + }; + r +} From aa44060f4ba8304de676cee3cf5eec7989d67302 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:20:33 +0200 Subject: [PATCH 03/28] arch: Handle SMAP violations in page faults Signed-off-by: Dennis Bonke --- .../src/arch/x86_64/interrupts/exceptions.rs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/aero_kernel/src/arch/x86_64/interrupts/exceptions.rs b/src/aero_kernel/src/arch/x86_64/interrupts/exceptions.rs index 0b8c16ce424..4eea3c55553 100644 --- a/src/aero_kernel/src/arch/x86_64/interrupts/exceptions.rs +++ b/src/aero_kernel/src/arch/x86_64/interrupts/exceptions.rs @@ -97,6 +97,23 @@ pub(super) fn page_fault(stack: &mut InterruptErrorStack) { log::error!("stack: {:#x?}", stack); }; + if reason.contains(PageFaultErrorCode::PROTECTION_VIOLATION) && !reason.contains(PageFaultErrorCode::USER_MODE) { + if controlregs::smap_enabled() { + unwind::prepare_panic(); + + log::error!("SMAP violation page fault"); + print_info(); + + controlregs::with_userspace_access(||unwind::unwind_stack_trace()); + + unsafe { + loop { + super::halt(); + } + } + } + } + if accessed_address < userland_last_address && scheduler::is_initialized() || stack.stack.iret.is_user() { @@ -130,7 +147,7 @@ pub(super) fn page_fault(stack: &mut InterruptErrorStack) { scheduler::get_scheduler().log_ptable(); } - unwind::unwind_stack_trace(); + controlregs::with_userspace_access(||unwind::unwind_stack_trace()); let task = scheduler::get_scheduler().current_task(); task.signal(aero_syscall::signal::SIGSEGV); @@ -147,7 +164,7 @@ pub(super) fn page_fault(stack: &mut InterruptErrorStack) { log::error!("Page fault"); print_info(); - unwind::unwind_stack_trace(); + controlregs::with_userspace_access(||unwind::unwind_stack_trace()); unsafe { loop { From 976d22597d0fb6d2c5c52b9cb8e4e912840ab19f Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:22:55 +0200 Subject: [PATCH 04/28] drivers/tty: Wrap userspace accesses for SMAP Signed-off-by: Dennis Bonke --- src/aero_kernel/src/drivers/tty.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/aero_kernel/src/drivers/tty.rs b/src/aero_kernel/src/drivers/tty.rs index 77822adc1c3..03c070e622d 100644 --- a/src/aero_kernel/src/drivers/tty.rs +++ b/src/aero_kernel/src/drivers/tty.rs @@ -28,6 +28,7 @@ use crate::fs::inode; use crate::fs::inode::INodeInterface; use crate::mem::paging::VirtAddr; use crate::utils::sync::{BlockQueue, Mutex}; +use crate::arch::controlregs; use super::keyboard::KeyCode; use super::keyboard::KeyboardListener; @@ -234,11 +235,11 @@ impl INodeInterface for Tty { if buffer.len() > stdin.front_buffer.len() { for (i, c) in stdin.front_buffer.drain(..).enumerate() { - buffer[i] = c; + controlregs::with_userspace_access(||buffer[i] = c); } } else { for (i, c) in stdin.front_buffer.drain(..buffer.len()).enumerate() { - buffer[i] = c; + controlregs::with_userspace_access(||buffer[i] = c); } } From 8c3caec51363c9233ab92d40abe6ad531a716a35 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:27:24 +0200 Subject: [PATCH 05/28] syscalls/fs: Wrap enough syscalls for aero_shell Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/fs.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/aero_kernel/src/syscall/fs.rs b/src/aero_kernel/src/syscall/fs.rs index 229958ef6fe..75aa1af0b44 100644 --- a/src/aero_kernel/src/syscall/fs.rs +++ b/src/aero_kernel/src/syscall/fs.rs @@ -20,6 +20,8 @@ use aero_syscall::prelude::FdFlags; use aero_syscall::{AeroSyscallError, OpenFlags}; +use crate::arch::controlregs; + use crate::fs::inode::DirEntry; use crate::fs::pipe::Pipe; use crate::fs::{self, lookup_path, LookupMode}; @@ -39,8 +41,8 @@ pub fn write(fd: usize, buffer: usize, size: usize) -> Result Result Result Result Result Result { @@ -224,7 +226,7 @@ pub fn getcwd(buffer: usize, size: usize) -> Result { let buffer = validate_slice_mut(buffer as *mut u8, size).ok_or(AeroSyscallError::EINVAL)?; let cwd = scheduler::get_scheduler().current_task().get_cwd(); - buffer[..cwd.len()].copy_from_slice(cwd.as_bytes()); + controlregs::with_userspace_access(||buffer[..cwd.len()].copy_from_slice(cwd.as_bytes())); Ok(cwd.len()) } From b0bc7c503daa77762027c6861d08ed00943e09a0 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:27:51 +0200 Subject: [PATCH 06/28] syscalls/ipc: Wrap enough syscalls for aero_shell Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/ipc.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/aero_kernel/src/syscall/ipc.rs b/src/aero_kernel/src/syscall/ipc.rs index ea0f76f98cc..860a61f8e4a 100644 --- a/src/aero_kernel/src/syscall/ipc.rs +++ b/src/aero_kernel/src/syscall/ipc.rs @@ -17,6 +17,7 @@ * along with Aero. If not, see . */ +use crate::arch::controlregs; use crate::userland::scheduler::get_scheduler; use crate::userland::task::TaskId; @@ -60,11 +61,10 @@ fn handle_recieve( let output = validate_slice_mut(message_ptr as *mut u8, message_size).ok_or(AeroSyscallError::EINVAL)?; - output[0..msg.data.len()].copy_from_slice(&msg.data); - - unsafe { + controlregs::with_userspace_access(||unsafe { + output[0..msg.data.len()].copy_from_slice(&msg.data); pid_ptr.write(msg.from); - } + }); Ok(msg.data.len()) } @@ -82,9 +82,11 @@ pub fn send(pid: usize, message: usize, message_size: usize) -> Result Date: Sun, 27 Mar 2022 17:28:17 +0200 Subject: [PATCH 07/28] syscalls/process: Wrap enough syscalls for aero_shell Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/process.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/aero_kernel/src/syscall/process.rs b/src/aero_kernel/src/syscall/process.rs index 8a8f438e1a4..2cee6f8d1d7 100644 --- a/src/aero_kernel/src/syscall/process.rs +++ b/src/aero_kernel/src/syscall/process.rs @@ -22,6 +22,8 @@ use aero_syscall::{AeroSyscallError, MMapFlags, MMapProt}; use alloc::string::String; use spin::{Mutex, Once}; +use crate::arch::controlregs; + use crate::fs; use crate::fs::Path; @@ -104,10 +106,10 @@ pub fn exec( envs: usize, envc: usize, ) -> Result { - let path = validate_str(path as *const u8, path_size).ok_or(AeroSyscallError::EINVAL)?; + let path = controlregs::with_userspace_access(||validate_str(path as *const u8, path_size).ok_or(AeroSyscallError::EINVAL))?; let path = Path::new(path); - let executable = fs::lookup_path(path)?; + let executable = controlregs::with_userspace_access(||fs::lookup_path(path))?; if executable.inode().metadata()?.is_directory() { return Err(AeroSyscallError::EISDIR); @@ -145,7 +147,7 @@ pub fn waitpid(pid: usize, status: usize, _flags: usize) -> Result Result if bytes.len() > slice.len() { Err(AeroSyscallError::ENAMETOOLONG) } else { - slice[0..bytes.len()].copy_from_slice(bytes); + controlregs::with_userspace_access(||slice[0..bytes.len()].copy_from_slice(bytes)); Ok(bytes.len()) } @@ -225,7 +227,7 @@ pub fn info(struc: usize) -> Result { let struc = unsafe { &mut *(struc as *mut aero_syscall::SysInfo) }; // TODO: Fill in the rest of the struct. - struc.uptime = crate::time::get_uptime_ticks() as i64; + controlregs::with_userspace_access(||struc.uptime = crate::time::get_uptime_ticks() as i64); Ok(0x00) } @@ -235,7 +237,7 @@ pub fn sethostname(ptr: usize, length: usize) -> Result match core::str::from_utf8(slice) { Ok(new_hostname) => { - *hostname().lock() = String::from(new_hostname); + controlregs::with_userspace_access(||*hostname().lock() = String::from(new_hostname)); Ok(0) } Err(_) => Err(AeroSyscallError::EINVAL), @@ -259,7 +261,7 @@ pub fn sigaction( }; let entry = if let Some(new) = new { - Some(SignalEntry::from_sigaction(*new, sigreturn)?) + Some(controlregs::with_userspace_access(||SignalEntry::from_sigaction(*new, sigreturn))?) } else { None }; @@ -278,7 +280,7 @@ pub fn sigaction( let task = scheduler.current_task(); let signals = task.signals(); - signals.set_signal(sig, entry, old); + controlregs::with_userspace_access(||signals.set_signal(sig, entry, old)); Ok(0) } From 073b032f4bb22792fb40ac60ed4fae3cb6df9e10 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:28:43 +0200 Subject: [PATCH 08/28] userland: Wrap some userspace access for SMAP Signed-off-by: Dennis Bonke --- src/aero_kernel/src/userland/task.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/aero_kernel/src/userland/task.rs b/src/aero_kernel/src/userland/task.rs index 255d823968b..0c0826eaa35 100644 --- a/src/aero_kernel/src/userland/task.rs +++ b/src/aero_kernel/src/userland/task.rs @@ -30,6 +30,7 @@ use crate::fs::{self, FileSystem}; use crate::mem::paging::*; use crate::arch::task::ArchTask; +use crate::arch::controlregs; use crate::fs::file_table::FileTable; use crate::syscall::{ExecArgs, MessageQueue}; use crate::utils::sync::{BlockQueue, Mutex}; @@ -154,9 +155,9 @@ impl Zombies { // WIFEXITED: The child process has been terminated normally by // either calling sys_exit() or returning from the main function. - *status = 0x200; + controlregs::with_userspace_access(||*status = 0x200); // The lower 8-bits are used to store the exit status. - *status |= st as u32 & 0xff; + controlregs::with_userspace_access(||*status |= st as u32 & 0xff); Ok(tid.as_usize()) } @@ -399,7 +400,7 @@ impl Task { // Clear the signals that are pending for this task on exec. self.signals().clear(); - self.arch_task_mut().exec(vm, executable, argv, envv) + controlregs::with_userspace_access(||self.arch_task_mut().exec(vm, executable, argv, envv)) } pub fn vm(&self) -> &Arc { From 5ce6160641dd51ea34803be82f8b656da5e57694 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:29:27 +0200 Subject: [PATCH 09/28] userland: Wrap more userspace access for SMAP Signed-off-by: Dennis Bonke --- src/aero_kernel/src/userland/vm.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/aero_kernel/src/userland/vm.rs b/src/aero_kernel/src/userland/vm.rs index e97a78180bc..bb72b916c1a 100644 --- a/src/aero_kernel/src/userland/vm.rs +++ b/src/aero_kernel/src/userland/vm.rs @@ -27,6 +27,7 @@ use xmas_elf::header::*; use xmas_elf::program::*; use xmas_elf::*; +use crate::arch::controlregs; use crate::arch::task::userland_last_address; use crate::fs; use crate::fs::cache::DirCacheItem; @@ -385,7 +386,7 @@ impl Mapping { let new_slice = new_frame.as_slice_mut::(); // Copy the contents from the old frame to the newly allocated frame. - new_slice.copy_from_slice(old_slice); + controlregs::with_userspace_access(||new_slice.copy_from_slice(old_slice)); // Re-map the page to the newly allocated frame and with the provided // protection flags. From 7e9f84699ce29ccba5e8ccb3cc4b18b1526dd5ad Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:29:51 +0200 Subject: [PATCH 10/28] arch: Initialize CPU features after initial logging is enabled Signed-off-by: Dennis Bonke --- src/aero_kernel/src/arch/x86_64/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/aero_kernel/src/arch/x86_64/mod.rs b/src/aero_kernel/src/arch/x86_64/mod.rs index d26b478b0d9..91cdcfefb78 100644 --- a/src/aero_kernel/src/arch/x86_64/mod.rs +++ b/src/aero_kernel/src/arch/x86_64/mod.rs @@ -146,9 +146,6 @@ extern "C" fn x86_64_aero_main(boot_info: &'static StivaleStruct) -> ! { .unwrap() }); - // Initialize the CPU specific features. - init_cpu(); - // We initialize the COM ports before doing anything else. // // This will help printing panics and logs before or when the debug renderer @@ -156,6 +153,9 @@ extern "C" fn x86_64_aero_main(boot_info: &'static StivaleStruct) -> ! { drivers::uart_16550::init(); logger::init(); + // Initialize the CPU specific features. + init_cpu(); + // Parse the kernel command line. let command_line: &'static _ = boot_info.command_line().map_or("", |cmd| unsafe { let cmdline = PhysAddr::new(cmd.command_line).as_hhdm_virt(); From 83f21d303c0dd1e2ee4e4e6edc3432fc90df7e6e Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 17:30:14 +0200 Subject: [PATCH 11/28] arch: Enable SMAP Signed-off-by: Dennis Bonke --- src/aero_kernel/src/arch/x86_64/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/aero_kernel/src/arch/x86_64/mod.rs b/src/aero_kernel/src/arch/x86_64/mod.rs index 91cdcfefb78..847ee24cd54 100644 --- a/src/aero_kernel/src/arch/x86_64/mod.rs +++ b/src/aero_kernel/src/arch/x86_64/mod.rs @@ -256,8 +256,20 @@ pub fn init_cpu() { } { + // Check if SMAP is supported. + let has_smap = CpuId::new() + .get_extended_feature_info() + .map_or(false, |i| i.has_smap()); + let mut cr4 = controlregs::read_cr4(); + if has_smap { + log::info!("SMAP is supported, enabling SMAP."); + cr4.insert(controlregs::Cr4Flags::SUPERVISOR_MODE_ACCESS_PREVENTION); + } else { + log::info!("SMAP is not supported."); + } + cr4.insert(controlregs::Cr4Flags::OSFXSR); cr4.insert(controlregs::Cr4Flags::OSXMMEXCPT_ENABLE); From 5f6a5c404886bfc93091c44771f64a081713ec92 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 23:42:48 +0200 Subject: [PATCH 12/28] aero_shell: Add missing newline to uptime Signed-off-by: Dennis Bonke --- userland/apps/aero_shell/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/userland/apps/aero_shell/src/main.rs b/userland/apps/aero_shell/src/main.rs index 75905eece31..fb24259aa81 100644 --- a/userland/apps/aero_shell/src/main.rs +++ b/userland/apps/aero_shell/src/main.rs @@ -144,7 +144,7 @@ fn repl(history: &mut Vec) -> Result<(), AeroSyscallError> { } "uptime" => { - print!("{}", get_uptime()?); + println!("{}", get_uptime()?); } "sleep" => { From 2957940d4aae1b7731525057ca5628c6c4677ead Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 23:57:57 +0200 Subject: [PATCH 13/28] chdir: Fix SMAP violation Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aero_kernel/src/syscall/fs.rs b/src/aero_kernel/src/syscall/fs.rs index 75aa1af0b44..0689add3cd2 100644 --- a/src/aero_kernel/src/syscall/fs.rs +++ b/src/aero_kernel/src/syscall/fs.rs @@ -138,7 +138,7 @@ pub fn close(fd: usize) -> Result { } pub fn chdir(path: usize, size: usize) -> Result { - let buffer = validate_str(path as *mut u8, size).ok_or(AeroSyscallError::EINVAL)?; + let buffer = controlregs::with_userspace_access(||validate_str(path as *mut u8, size).ok_or(AeroSyscallError::EINVAL))?; let inode = fs::lookup_path(Path::new(buffer))?; if !inode.inode().metadata()?.is_directory() { From 4920a7b95391c72b945a3d8e5bbc29632d7bde7c Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 23:58:14 +0200 Subject: [PATCH 14/28] mkdir: Fix SMAP violation Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aero_kernel/src/syscall/fs.rs b/src/aero_kernel/src/syscall/fs.rs index 0689add3cd2..42659fb4e45 100644 --- a/src/aero_kernel/src/syscall/fs.rs +++ b/src/aero_kernel/src/syscall/fs.rs @@ -151,7 +151,7 @@ pub fn chdir(path: usize, size: usize) -> Result { } pub fn mkdirat(dfd: usize, path: usize, size: usize) -> Result { - let path_str = validate_str(path as *mut u8, size).ok_or(AeroSyscallError::EINVAL)?; + let path_str = controlregs::with_userspace_access(||validate_str(path as *mut u8, size).ok_or(AeroSyscallError::EINVAL))?; let path = Path::new(path_str); // NOTE: If the pathname given in pathname is relative, then it is interpreted From 762cc9c01a381fb6e2bf9daa3d0934f70b1c2efa Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 23:58:24 +0200 Subject: [PATCH 15/28] rmdir: Fix SMAP violation Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aero_kernel/src/syscall/fs.rs b/src/aero_kernel/src/syscall/fs.rs index 42659fb4e45..06e2a63911c 100644 --- a/src/aero_kernel/src/syscall/fs.rs +++ b/src/aero_kernel/src/syscall/fs.rs @@ -199,7 +199,7 @@ pub fn mkdir(path: usize, size: usize) -> Result { } pub fn rmdir(path: usize, size: usize) -> Result { - let path_str = validate_str(path as *mut u8, size).ok_or(AeroSyscallError::EINVAL)?; + let path_str = controlregs::with_userspace_access(||validate_str(path as *mut u8, size).ok_or(AeroSyscallError::EINVAL))?; let path = Path::new(path_str); let (_, child) = path.parent_and_basename(); From 5a701b402b6580aeaaa4cbe92787ce70ed056219 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Sun, 27 Mar 2022 23:58:37 +0200 Subject: [PATCH 16/28] uname: Fix SMAP violation Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aero_kernel/src/syscall/process.rs b/src/aero_kernel/src/syscall/process.rs index 2cee6f8d1d7..0925f9535e5 100644 --- a/src/aero_kernel/src/syscall/process.rs +++ b/src/aero_kernel/src/syscall/process.rs @@ -59,7 +59,7 @@ pub fn uname(buffer: usize) -> Result { let init_bytes = init.as_bytes(); let len = init.len(); - fixed[..len].copy_from_slice(init_bytes) + controlregs::with_userspace_access(||fixed[..len].copy_from_slice(init_bytes)) } // TODO: Safety checks! From 3aeabdd4d25a8582e329889f15349c179cf37256 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 00:13:03 +0200 Subject: [PATCH 17/28] binutils: Only build the needed things for host-binutils Signed-off-by: Dennis Bonke --- bootstrap.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap.yml b/bootstrap.yml index 1aacef0a1ba..3aba7989d61 100644 --- a/bootstrap.yml +++ b/bootstrap.yml @@ -236,9 +236,9 @@ tools: # -g blows up the binary size. - 'CFLAGS=-pipe' compile: - - args: ['make', '-j@PARALLELISM@'] + - args: ['make', '-j@PARALLELISM@', 'all-binutils', 'all-gas', 'all-ld'] install: - - args: ['make', 'install'] + - args: ['make', 'install-binutils', 'install-gas', 'install-ld'] - name: host-gcc from_source: gcc From d7fcf8d6677e39957b931266dd0ce38c017fff52 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:41:53 +0200 Subject: [PATCH 18/28] signals: Fix SMAP violations Signed-off-by: Dennis Bonke --- src/aero_kernel/src/arch/x86_64/signals.rs | 5 +++-- src/aero_kernel/src/userland/signals.rs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/aero_kernel/src/arch/x86_64/signals.rs b/src/aero_kernel/src/arch/x86_64/signals.rs index 21ad2ccd4f4..620892da028 100644 --- a/src/aero_kernel/src/arch/x86_64/signals.rs +++ b/src/aero_kernel/src/arch/x86_64/signals.rs @@ -20,6 +20,7 @@ use crate::userland; use crate::userland::scheduler; use crate::utils::StackHelper; +use crate::arch::controlregs; use super::interrupts::InterruptStack; @@ -107,11 +108,11 @@ pub fn sigreturn(stack: &mut InterruptStack) -> usize { let current_task = scheduler::get_scheduler().current_task(); - current_task.signals().set_mask( + controlregs::with_userspace_access(||current_task.signals().set_mask( aero_syscall::signal::SigProcMask::Set, signal_frame.sigmask, None, - ); + )); writer.get_by(REDZONE_SIZE); diff --git a/src/aero_kernel/src/userland/signals.rs b/src/aero_kernel/src/userland/signals.rs index 7cefd53d4c7..b97684411c7 100644 --- a/src/aero_kernel/src/userland/signals.rs +++ b/src/aero_kernel/src/userland/signals.rs @@ -29,6 +29,7 @@ use bit_field::BitField; use aero_syscall::AeroSyscallError; use super::scheduler; +use crate::arch::controlregs; use crate::fs::FileSystemError; use crate::utils::sync::{Mutex, MutexGuard}; @@ -391,7 +392,7 @@ impl Signals { *old = self.blocked_mask.load(Ordering::SeqCst); } - let set = set & !IMMUTABLE_MASK; + let set = controlregs::with_userspace_access(||set & !IMMUTABLE_MASK); match how { SigProcMask::Block => { From bbeb33fbfde28fb2f58465ecd9fa73e05230bccb Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:42:17 +0200 Subject: [PATCH 19/28] tty: Fix more SMAP violations Signed-off-by: Dennis Bonke --- src/aero_kernel/src/drivers/tty.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/aero_kernel/src/drivers/tty.rs b/src/aero_kernel/src/drivers/tty.rs index 03c070e622d..bef794c5e6e 100644 --- a/src/aero_kernel/src/drivers/tty.rs +++ b/src/aero_kernel/src/drivers/tty.rs @@ -265,13 +265,13 @@ impl INodeInterface for Tty { let (rows, cols) = crate::rendy::get_rows_cols(); - winsize.ws_row = rows as u16; - winsize.ws_col = cols as u16; + controlregs::with_userspace_access(||winsize.ws_row = rows as u16); + controlregs::with_userspace_access(||winsize.ws_col = cols as u16); let (xpixel, ypixel) = crate::rendy::get_resolution(); - winsize.ws_xpixel = xpixel as u16; - winsize.ws_ypixel = ypixel as u16; + controlregs::with_userspace_access(||winsize.ws_xpixel = xpixel as u16); + controlregs::with_userspace_access(||winsize.ws_ypixel = ypixel as u16); Ok(0x00) } @@ -283,7 +283,7 @@ impl INodeInterface for Tty { let lock = TERMIOS.lock_irq(); let this = &*lock; - *termios = this.clone(); + controlregs::with_userspace_access(||*termios = this.clone()); Ok(0x00) } @@ -300,7 +300,7 @@ impl INodeInterface for Tty { let mut lock = TERMIOS.lock_irq(); let this = &mut *lock; - *this = termios.clone(); + controlregs::with_userspace_access(||*this = termios.clone()); Ok(0x00) } From 50e5479aa73a83b3625b03b34593d9ac18604dad Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:42:39 +0200 Subject: [PATCH 20/28] fs: Fix pipe and access SMAP violations Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/fs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/aero_kernel/src/syscall/fs.rs b/src/aero_kernel/src/syscall/fs.rs index 06e2a63911c..f29b52f298d 100644 --- a/src/aero_kernel/src/syscall/fs.rs +++ b/src/aero_kernel/src/syscall/fs.rs @@ -277,8 +277,8 @@ pub fn pipe(fds: usize, flags: usize) -> Result { Ok(fd2) => fd2, }; - fds[0] = fd1; - fds[1] = fd2; + controlregs::with_userspace_access(||fds[0] = fd1); + controlregs::with_userspace_access(||fds[1] = fd2); Ok(0x00) } @@ -321,7 +321,7 @@ pub fn access( _mode: usize, _flags: usize, ) -> Result { - let path_str = validate_str(path as *mut u8, path_size).ok_or(AeroSyscallError::EINVAL)?; + let path_str = controlregs::with_userspace_access(||validate_str(path as *mut u8, path_size).ok_or(AeroSyscallError::EINVAL))?; let path = Path::new(path_str); if fd as isize == aero_syscall::AT_FDCWD { From d1a71cc272e746dc7bf02d6242edce971260026b Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:42:57 +0200 Subject: [PATCH 21/28] syscall/log: Fix SMAP violation Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aero_kernel/src/syscall/process.rs b/src/aero_kernel/src/syscall/process.rs index 0925f9535e5..2df640b28fa 100644 --- a/src/aero_kernel/src/syscall/process.rs +++ b/src/aero_kernel/src/syscall/process.rs @@ -137,7 +137,7 @@ pub fn exec( } pub fn log(msg_start: usize, msg_size: usize) -> Result { - let message = validate_str(msg_start as *const u8, msg_size).ok_or(AeroSyscallError::EINVAL)?; + let message = controlregs::with_userspace_access(||validate_str(msg_start as *const u8, msg_size).ok_or(AeroSyscallError::EINVAL))?; log::debug!("{}", message); Ok(0x00) From 046a2ad07f6eea2b646ef9e51db531177d812511 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:43:25 +0200 Subject: [PATCH 22/28] time: Fix several SMAP violations Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/time.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/aero_kernel/src/syscall/time.rs b/src/aero_kernel/src/syscall/time.rs index ab38eccc441..34707528fdc 100644 --- a/src/aero_kernel/src/syscall/time.rs +++ b/src/aero_kernel/src/syscall/time.rs @@ -19,6 +19,7 @@ use aero_syscall::AeroSyscallError; +use crate::arch::controlregs; use crate::utils::CeilDiv; use crate::{mem::paging::VirtAddr, userland::scheduler}; @@ -28,7 +29,7 @@ const CLOCK_TYPE_MONOTONIC: usize = 1; pub fn sleep(timespec: usize) -> Result { let timespec = VirtAddr::new(timespec as u64); let timespec = unsafe { &*(timespec.as_mut_ptr::()) }; - let duration = (timespec.tv_nsec as usize).ceil_div(1000000000) + timespec.tv_sec as usize; + let duration = controlregs::with_userspace_access(||(timespec.tv_nsec as usize).ceil_div(1000000000) + timespec.tv_sec as usize); scheduler::get_scheduler().inner.sleep(Some(duration))?; @@ -43,8 +44,8 @@ pub fn gettime(clock: usize, timespec: usize) -> Result CLOCK_TYPE_REALTIME => { let clock = crate::time::get_realtime_clock(); - timespec.tv_sec = clock.tv_sec; - timespec.tv_nsec = clock.tv_nsec; + controlregs::with_userspace_access(||timespec.tv_sec = clock.tv_sec); + controlregs::with_userspace_access(||timespec.tv_nsec = clock.tv_nsec); Ok(0x00) } From 8c5bd393e10c28af696a3bd1fcee6e7f67195a60 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:45:22 +0200 Subject: [PATCH 23/28] aero.py: Request SMEP and UMIP if possible Signed-off-by: Dennis Bonke --- aero.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aero.py b/aero.py index f4b1d63b9f4..de2b7637483 100755 --- a/aero.py +++ b/aero.py @@ -470,11 +470,11 @@ def run_in_emulator(args, iso_path): print("Running with KVM acceleration enabled") if platform.system() == 'Darwin': - qemu_args += ['-accel', 'hvf', '-cpu', 'qemu64,+la57,+smap' if args.la57 else 'qemu64,+smap'] + qemu_args += ['-accel', 'hvf', '-cpu', 'qemu64,+la57,+smap,+smep,+umip' if args.la57 else 'qemu64,+smap,+smep,+umip'] else: - qemu_args += ['-enable-kvm', '-cpu', 'host,+la57,+smap' if args.la57 else 'host,+smap'] + qemu_args += ['-enable-kvm', '-cpu', 'host,+la57,+smap,+smep,+umip' if args.la57 else 'host,+smap,+smep,+umip'] else: - qemu_args += ["-cpu", "qemu64,+la57,+smap" if args.la57 else "qemu64,+smap"] + qemu_args += ["-cpu", "qemu64,+la57,+smap,+smep,+umip" if args.la57 else "qemu64,+smap,+smep,+umip"] run_command(['qemu-system-x86_64', *qemu_args]) From aee1c6a48eb226ecf127f7981a5142b25d747d90 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:50:08 +0200 Subject: [PATCH 24/28] unwind: Fix SMAP violation Signed-off-by: Dennis Bonke --- src/aero_kernel/src/unwind.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/aero_kernel/src/unwind.rs b/src/aero_kernel/src/unwind.rs index 10a7b13205a..531c1df9858 100644 --- a/src/aero_kernel/src/unwind.rs +++ b/src/aero_kernel/src/unwind.rs @@ -32,6 +32,7 @@ use crate::logger; use crate::rendy; use crate::arch::interrupts; +use crate::arch::controlregs; static PANIC_HOOK_READY: AtomicBool = AtomicBool::new(false); @@ -186,7 +187,7 @@ extern "C" fn rust_begin_unwind(info: &PanicInfo) -> ! { // Add a new line to make the stack trace more readable. log::error!(""); - unwind_stack_trace(); + controlregs::with_userspace_access(||unwind_stack_trace()); #[cfg(feature = "ci")] emu::exit_qemu(emu::ExitStatus::Success); From 9d030f4697c298d3ca35a72c64fc7ce70ede3f68 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 11:53:08 +0200 Subject: [PATCH 25/28] x86_64: Enable write protect Signed-off-by: Dennis Bonke --- src/aero_kernel/src/arch/x86_64/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aero_kernel/src/arch/x86_64/mod.rs b/src/aero_kernel/src/arch/x86_64/mod.rs index 847ee24cd54..14c4b88d248 100644 --- a/src/aero_kernel/src/arch/x86_64/mod.rs +++ b/src/aero_kernel/src/arch/x86_64/mod.rs @@ -251,6 +251,7 @@ pub fn init_cpu() { cr0.remove(controlregs::Cr0Flags::EMULATE_COPROCESSOR); cr0.insert(controlregs::Cr0Flags::MONITOR_COPROCESSOR); + cr0.insert(controlregs::Cr0Flags::WRITE_PROTECT); controlregs::write_cr0(cr0); } From 857014b0de63aee9939ca5124c75a46c21c220be Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 12:12:36 +0200 Subject: [PATCH 26/28] unlink: Fix SMAP violation Signed-off-by: Dennis Bonke --- src/aero_kernel/src/syscall/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aero_kernel/src/syscall/fs.rs b/src/aero_kernel/src/syscall/fs.rs index f29b52f298d..28f77d07192 100644 --- a/src/aero_kernel/src/syscall/fs.rs +++ b/src/aero_kernel/src/syscall/fs.rs @@ -289,7 +289,7 @@ pub fn unlink( path_size: usize, flags: usize, ) -> Result { - let path_str = validate_str(path as *mut u8, path_size).ok_or(AeroSyscallError::EINVAL)?; + let path_str = controlregs::with_userspace_access(||validate_str(path as *mut u8, path_size).ok_or(AeroSyscallError::EINVAL))?; let path = Path::new(path_str); // TODO: Make use of the open flags. From df63f690e618018696161f449c2e8c6e727884e6 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 12:12:49 +0200 Subject: [PATCH 27/28] x86_64: Enable SMEP Signed-off-by: Dennis Bonke --- src/aero_kernel/src/arch/x86_64/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/aero_kernel/src/arch/x86_64/mod.rs b/src/aero_kernel/src/arch/x86_64/mod.rs index 14c4b88d248..a989ce834e1 100644 --- a/src/aero_kernel/src/arch/x86_64/mod.rs +++ b/src/aero_kernel/src/arch/x86_64/mod.rs @@ -262,6 +262,11 @@ pub fn init_cpu() { .get_extended_feature_info() .map_or(false, |i| i.has_smap()); + // Check if SMEP is supported. + let has_smep = CpuId::new() + .get_extended_feature_info() + .map_or(false, |i| i.has_smep()); + let mut cr4 = controlregs::read_cr4(); if has_smap { @@ -271,6 +276,13 @@ pub fn init_cpu() { log::info!("SMAP is not supported."); } + if has_smep { + log::info!("SMEP is supported, enabling SMEP."); + cr4.insert(controlregs::Cr4Flags::SUPERVISOR_MODE_EXECUTION_PROTECTION); + } else { + log::info!("SMEP is not supported."); + } + cr4.insert(controlregs::Cr4Flags::OSFXSR); cr4.insert(controlregs::Cr4Flags::OSXMMEXCPT_ENABLE); From eaae9d2294112be087da4b2832b643f40abb3662 Mon Sep 17 00:00:00 2001 From: Dennis Bonke Date: Mon, 28 Mar 2022 12:15:15 +0200 Subject: [PATCH 28/28] x86_64: Enable UMIP Signed-off-by: Dennis Bonke --- src/aero_kernel/src/arch/x86_64/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/aero_kernel/src/arch/x86_64/mod.rs b/src/aero_kernel/src/arch/x86_64/mod.rs index a989ce834e1..2fb8293ed3b 100644 --- a/src/aero_kernel/src/arch/x86_64/mod.rs +++ b/src/aero_kernel/src/arch/x86_64/mod.rs @@ -267,6 +267,11 @@ pub fn init_cpu() { .get_extended_feature_info() .map_or(false, |i| i.has_smep()); + // Check if UMIP is supported. + let has_umip = CpuId::new() + .get_extended_feature_info() + .map_or(false, |i| i.has_umip()); + let mut cr4 = controlregs::read_cr4(); if has_smap { @@ -283,6 +288,13 @@ pub fn init_cpu() { log::info!("SMEP is not supported."); } + if has_umip { + log::info!("UMIP is supported, enabling UMIP."); + cr4.insert(controlregs::Cr4Flags::USER_MODE_INSTRUCTION_PREVENTION); + } else { + log::info!("UMIP is not supported."); + } + cr4.insert(controlregs::Cr4Flags::OSFXSR); cr4.insert(controlregs::Cr4Flags::OSXMMEXCPT_ENABLE);