Skip to content

Commit

Permalink
mem: Implement safe copy functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Qwinci committed Aug 26, 2023
1 parent 4d4f532 commit a47c517
Show file tree
Hide file tree
Showing 20 changed files with 169 additions and 98 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/it-compiles-test.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
name: It Compiles!
on: [push]
on: [push, workflow_dispatch]
jobs:
Compile:
runs-on: ubuntu-latest
container: archlinux:latest
#container: archlinux:latest
container: ubuntu:latest
steps:
- name: Install dependencies
#run: >
# pacman -Sy --noconfirm --needed glibc clang nasm lld cmake ninja xorriso git
run: >
pacman -Sy --noconfirm --needed glibc clang nasm lld cmake ninja xorriso git
apt-get install clang lld cmake ninja-build xorriso -y
- name: Checkout repository
uses: actions/checkout@v3
- name: Configure source
Expand Down
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ set(FILES
${PROJECT_SOURCE_DIR}/limine.cfg
crescent
user_tty
initramfs.tar
)

add_executable(crescent src/main.c)
Expand All @@ -26,7 +25,7 @@ target_compile_options(crescent PRIVATE
-mgeneral-regs-only -mno-red-zone -mcmodel=kernel
-fno-stack-protector -fno-exceptions -fno-rtti
-fno-omit-frame-pointer
-fPIC -nostdlibinc -fno-builtin>)
-fPIC -nostdlibinc -Werror=switch -Werror=noderef>)
target_compile_options(crescent PRIVATE $<$<COMPILE_LANGUAGE:ASM>: -Wno-unused-command-line-argument>)
target_link_options(crescent PRIVATE -T ${PROJECT_SOURCE_DIR}/.config/kernel.ld)

Expand Down
10 changes: 10 additions & 0 deletions include/crescent/handle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef CRESCENT_HANDLE_H
#define CRESCENT_HANDLE_H

#include <stdint.h>

#define INVALID_HANDLE ((Handle) -1)

typedef uint64_t Handle;

#endif
6 changes: 1 addition & 5 deletions include/crescent/sys.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#ifndef CRESCENT_SYS_H
#define CRESCENT_SYS_H
#include <stdint.h>

#define INVALID_HANDLE ((Handle) -1)

typedef uint64_t Handle;
#include "handle.h"

typedef enum {
SHUTDOWN_TYPE_REBOOT
Expand Down
3 changes: 0 additions & 3 deletions limine.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@ MODULE_CMDLINE=Tamsyn8x16r.psf
MODULE_PATH=boot:///user_tty
MODULE_CMDLINE=user_tty

MODULE_PATH=boot:///initramfs.tar
MODULE_CMDLINE=initramfs.tar

KASLR=no
8 changes: 7 additions & 1 deletion src/arch/misc.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#pragma once
#include "types.h"

void arch_hlt();
void arch_spinloop_hint();

void arch_reboot();
void arch_reboot();

#define __user __attribute__((address_space(1), noderef))

bool arch_mem_copy_to_user(__user void* restrict user, const void* restrict kernel, usize size);
bool arch_mem_copy_to_kernel(void* restrict kernel, __user const void* restrict user, usize size);
1 change: 1 addition & 0 deletions src/arch/x86/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ target_sources(crescent PRIVATE
mod.c
mem/map.c
mem/mem.c
mem/misc.S
interrupts/interrupts.c
interrupts/idt.c
interrupts/int_stubs.S
Expand Down
18 changes: 8 additions & 10 deletions src/arch/x86/interrupts/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ GENERIC_EX(security, "security exception")
IrqStatus ex_pf(void* void_ctx, void*) {
InterruptCtx* ctx = (InterruptCtx*) void_ctx;

Task* self = arch_get_cur_task();
if (self->handler_ip) {
ctx->ip = (usize) self->handler_ip;
ctx->sp = (usize) self->handler_sp;
self->handler_ip = 0;
return IRQ_ACK;
}

bool present = ctx->error & 1;
bool write = ctx->error & 1 << 1;
bool user = ctx->error & 1 << 2;
Expand Down Expand Up @@ -92,21 +100,11 @@ IrqStatus ex_pf(void* void_ctx, void*) {
backtrace_display(false);
spinlock_unlock(&PRINT_LOCK);

Task* self = arch_get_cur_task();
if (ctx->cs == 0x2b) {
kprintf("killing user task '%s'\n", self->name);
__asm__ volatile("sti");
sched_kill_cur();
}
else if (self->inside_syscall) {
ctx->sp = ctx->rbp + 8;
ctx->rbp = *(const u64*) ctx->rbp;
ctx->ip = *(const u64*) ctx->sp;
ctx->sp += 8;
ctx->rax = ERR_FAULT;
kprintf("%" PRIfg, COLOR_RESET);
return IRQ_ACK;
}

lapic_ipi_all(LAPIC_MSG_PANIC);

Expand Down
45 changes: 45 additions & 0 deletions src/arch/x86/mem/misc.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// bool arch_mem_copy_to_user(__user void* restrict user, const void* restrict kernel, usize size);
// bool arch_mem_copy_to_kernel(void* restrict kernel, __user const void* restrict user, usize size);

#include <arch/x86/sched/usermode.inc>

.globl arch_mem_copy_to_user
.globl arch_mem_copy_to_kernel

.type arch_mem_copy_to_user, @function
arch_mem_copy_to_user:
push %rbp
mov %rsp, %rbp

lea 1f(%rip), %rax
mov %rax, %gs:X86TASK_HANDLER_IP_OFF
mov %rsp, %gs:X86TASK_HANDLER_SP_OFF

call memcpy

pop %rbp
mov $1, %eax
ret
1:
pop %rbp
xor %eax, %eax
ret

.type arch_mem_copy_to_kernel, @function
arch_mem_copy_to_kernel:
push %rbp
mov %rsp, %rbp

lea 1f(%rip), %rax
mov %rax, %gs:X86TASK_HANDLER_IP_OFF
mov %rsp, %gs:X86TASK_HANDLER_SP_OFF

call memcpy

pop %rbp
mov $1, %eax
ret
1:
pop %rbp
xor %eax, %eax
ret
3 changes: 2 additions & 1 deletion src/arch/x86/sched/usermode.inc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef USERMODE_INC
#define USERMODE_INC

#define X86TASK_INSIDE_SYSCALL_OFFSET 380
#define X86TASK_HANDLER_IP_OFF 368
#define X86TASK_HANDLER_SP_OFF 376

#endif
12 changes: 9 additions & 3 deletions src/arch/x86/sched/x86_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ typedef struct X86Task {
bool user;
} X86Task;

#define X86TASK_COMMON_OFF 72
#define TASK_HANDLER_IP_OFF 296
#define TASK_HANDLER_SP_OFF 304

#include "usermode.inc"
static_assert(offsetof(X86Task, common) + offsetof(Task, inside_syscall) == X86TASK_INSIDE_SYSCALL_OFFSET);
static_assert(offsetof(Task, inside_syscall) == 308);
static_assert(offsetof(X86Task, common) == 72);
static_assert(offsetof(X86Task, common) == X86TASK_COMMON_OFF);
static_assert(offsetof(Task, handler_ip) == TASK_HANDLER_IP_OFF);
static_assert(offsetof(Task, handler_sp) == TASK_HANDLER_SP_OFF);
static_assert(X86TASK_COMMON_OFF + TASK_HANDLER_IP_OFF == X86TASK_HANDLER_IP_OFF);
static_assert(X86TASK_COMMON_OFF + TASK_HANDLER_SP_OFF == X86TASK_HANDLER_SP_OFF);

void x86_task_add_map_page(X86Task* task, struct Page* page);
void x86_task_remove_map_page(X86Task* task, struct Page* page);
10 changes: 10 additions & 0 deletions src/mem/user.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once
#include "arch/misc.h"

static inline bool mem_copy_to_user(__user void* restrict user, const void* restrict kernel, usize size) {
return arch_mem_copy_to_user(user, kernel, size);
}

static inline bool mem_copy_to_kernel(void* restrict kernel, __user const void* restrict user, usize size) {
return arch_mem_copy_to_kernel(kernel, user, size);
}
6 changes: 1 addition & 5 deletions src/mem/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void* vm_user_alloc_backed(Process* process, usize count, PageFlags flags, void*
}

mutex_lock(&process->mapping_lock);
if (!process_add_mapping(process, (usize) vm, count * PAGE_SIZE)) {
if (!process_add_mapping(process, (usize) vm, count * PAGE_SIZE, flags & PF_WRITE)) {
mutex_unlock(&process->mapping_lock);
vm_user_dealloc(process, vm, count);
if (kernel_vm) {
Expand Down Expand Up @@ -192,7 +192,3 @@ bool vm_user_dealloc_backed(Process* process, void* ptr, usize count, void* kern
}
return true;
}

bool vm_user_verify(Process* process, void* ptr, size_t len) {
return process_is_mapped(process, (usize) ptr, len);
}
2 changes: 0 additions & 2 deletions src/mem/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,3 @@ void vm_user_dealloc(Process* process, void* ptr, usize count);
void* vm_user_alloc_backed(Process* process, usize count, PageFlags flags, void** kernel_mapping);
void vm_user_dealloc_kernel(void* kernel_mapping, usize count);
bool vm_user_dealloc_backed(Process* process, void* ptr, usize count, void* kernel_mapping);

bool vm_user_verify(Process* process, void* ptr, size_t len);
15 changes: 8 additions & 7 deletions src/sched/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,36 @@ Mapping* process_find_mapping(Process* self, usize addr) {
return NULL;
}

bool process_is_mapped(Process* self, usize start, usize size) {
usize end = start + size;
bool process_is_mapped(Process* self, const void* start, usize size, bool rw) {
usize end = (usize) start + size;

const Mapping* mapping = (const Mapping*) self->mappings.hook.root;
while (mapping) {
usize mapping_start = mapping->base;
usize mapping_end = mapping_start + mapping->size;

if (start < mapping_end && mapping_start < end) {
return true;
if ((usize) start < mapping_end && mapping_start < end) {
return !rw || mapping->rw;
}

if (start < mapping->base) {
if ((usize) start < mapping->base) {
mapping = (const Mapping*) mapping->hook.left;
}
else if (start > mapping->base) {
else if ((usize) start > mapping->base) {
mapping = (const Mapping*) mapping->hook.right;
}
}
return false;
}

bool process_add_mapping(Process* self, usize base, usize size) {
bool process_add_mapping(Process* self, usize base, usize size, bool rw) {
Mapping* mapping = kcalloc(sizeof(Mapping));
if (!mapping) {
return false;
}
mapping->base = base;
mapping->size = size;
mapping->rw = rw;

Mapping* m = (Mapping*) self->mappings.hook.root;
if (!m) {
Expand Down
5 changes: 3 additions & 2 deletions src/sched/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ typedef struct {
RbTreeNode hook;
usize base;
usize size;
bool rw;
} Mapping;

typedef struct {
Expand All @@ -30,8 +31,8 @@ typedef struct Process {

Process* process_new();
Process* process_new_user();
bool process_add_mapping(Process* self, usize base, usize size);
bool process_add_mapping(Process* self, usize base, usize size, bool rw);
bool process_remove_mapping(Process* self, usize base);
bool process_is_mapped(Process* self, usize start, usize size);
bool process_is_mapped(Process* self, const void* start, usize size, bool rw);
void process_add_thread(Process* self, Task* task);
void process_remove_thread(Process* self, Task* task);
3 changes: 2 additions & 1 deletion src/sched/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@ typedef struct Task {
struct Task* signal_waiters;
Mutex signal_waiters_lock;
EventQueue event_queue;
void* handler_ip;
void* handler_sp;
TaskStatus status;
u32 caps;
u8 level;
u8 priority;
bool pin_level;
bool pin_cpu;
bool inside_syscall;
atomic_bool killed;
} Task;

Expand Down
Loading

0 comments on commit a47c517

Please sign in to comment.