kernel: Various changes
+ elf: Prevent dynamically linked programs from running on Soaplin. + sched: Support creating a process from a program_t structure. + syscall: Fix a bug where using syscall number 1024 would crash the OS. + syscall: Added a write syscall. It can only be used for writing to the standard output (FD: 1)
This commit is contained in:
parent
1e84bcedc9
commit
0652010b1c
9 changed files with 44 additions and 6 deletions
|
@ -47,6 +47,12 @@ program_t *elf_load(char *data, int user) {
|
|||
|
||||
for (uint16_t i = 0; i < ehdr->e_phnum; i++) {
|
||||
log("elf - ELF segment type: %d\n", phdr[i].p_type);
|
||||
|
||||
if (phdr[i].p_type == PT_INTERP) {
|
||||
log("elf - A PT_INTERP program header was found. This was meant to be a dynamically-linked program, which Soaplin doesn't supports.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (phdr[i].p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
|
@ -58,7 +64,9 @@ program_t *elf_load(char *data, int user) {
|
|||
uint64_t flags = VMM_PRESENT;
|
||||
if (phdr[i].p_flags & PF_W)
|
||||
flags |= VMM_WRITABLE;
|
||||
if (!(phdr[i].p_flags & PF_X))
|
||||
if (phdr[i].p_flags & PF_X)
|
||||
flags &= ~VMM_NX;
|
||||
else
|
||||
flags |= VMM_NX;
|
||||
|
||||
if (user)
|
||||
|
|
|
@ -131,7 +131,7 @@ void __kmain(void) {
|
|||
|
||||
|
||||
sched_process *proc =
|
||||
sched_create("Test", p->entry, p->pm, SCHED_USER_PROCESS);
|
||||
sched_from_program(p);
|
||||
|
||||
log("kernel - Soaplin initialized sucessfully.\n");
|
||||
|
||||
|
|
|
@ -119,6 +119,10 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
|
|||
return proc;
|
||||
}
|
||||
|
||||
sched_process *sched_from_program(program_t *prog) {
|
||||
// D̶̡͖̼̪̩̽̃̿͐͐̀̑͐̑ǫ̴͚̘̩̗̠̣̗͇̳̀̅̈͌͆͆ ̸̢̢̯͎̳̟̑͋́N̷̹͛̋͗ö̴͇̼̖̝̼́̀̾̿̾̓̔̌t̵̯̘͇̙̬̤̫͚͓̠͔̭̚ͅ ̵͔̲͈̭͛̆̈Ú̷̱̈́͑́̇̀̈́̔͝͠s̴̢͇̳̯̬͔̦̗̯̜̀̓̎̆̅̈́̈́̑̾͆͌̆͝ê̴̛͎̪̩̙͕̖͖͍͓͐̊̈͋̆̂̌̍̂͘͘̚ ̵̢̢͖̦̬͔̻͇̠̺̂͒͌͌̈́̇̏͑͋̓̔̅̓͂͝S̴̡͇͎̠̯͙̖̲̮͓͋͊̐̋̑́͂͆̿C̵̤̲͉̫̜͓͇̙͇̪̥̈̂́̈́͋̃̿̕H̶̡͓̠̝͉͋͋̎̃E̶͉̬̞̖̮͚̙͗̔̋͆Ḑ̴̛͎̙̥̱̱͎͊͊͋̈́̆̎̓͑̚̚_̷͚̯̻̖͈̳̺̖̈͗́̽͠Ḱ̴̮͓̲̠̫͈̆̿͂͂̀̂͆̀́̔͝ͅḘ̷̡͔̘̒̒̐͆̍̀R̵̭̰̐́̾̈́̈́̋͗̎̉͐͝N̴̰͆̂͛̂̈́̄̊͌̓͆̕͘͠͠Ě̴̥͙̼̳̩̠͓͕̫͔̘̠̻̀͌̓͑́̓̂̋̌͘͜L̴̙͓̣̭̙͙͈̺̩̄̈͆͆͒͗͛̈́̎̉̈́͘͘͜͠_̵̭̱͇͍̩̬͌̿͂͊̐͘̕ͅP̵̡̪̹̀͂̀̋̇̓͘͜Ŕ̸̭͍̮̼̙͓͕̳̫̇̏͌͌̋͜͝Ǫ̵̛͎̭̱͈̫̮̘͉͔̪̟̺̥̉̈̈́̊́̕̕͠ͅC̵̡̡͕̱̠̝̭͓̗̜͇̼̳̲͓̑̽̔̑͠Ę̷̛̦̑̈̒̃̊̈́̓̚̚͜͠͝Ş̴̥͇̬̱̠̟͙̳̖̿͗̀͌͊̽̐͒̃͜S̴͉͖͉͎͎̱̝͔̙̜̭̍͑͊̒͆̃͗̂͌̽͑̓ͅ ̶̼̥̜͙͈̦̲̰̞̈́̑͆̂͝H̸̩̭̹̘̩̊͗̔̉̓̈́ȩ̷̩͍͚̮̰̭̘͍͇͈̺͇̻̓̀̅̊́̓̈́͗̇̔̓͛͜͝ṙ̶̡̩̜̜̭̝̪͔͙̟̣͉̆͗̉͜͠͝ͅę̷̡̦̘̰͖̲͉̤̼͈̺̺̦̯̿͌́͐̃̃͂̾́̊́.̶̡̧͈͍͈̟̠͙̘̤̝̪̽̊̈͐̕͜
|
||||
return sched_create("unknown program", prog->entry, prog->pm, SCHED_USER_PROCESS);
|
||||
}
|
||||
void sched_exit(int exit_code) {
|
||||
log("sched - Process %d exited with code %d!", curr_proc->pid, exit_code);
|
||||
curr_proc->type = SCHED_DIED;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "arch/x86_64/idt.h"
|
||||
#include "exec/exec.h"
|
||||
#include "mm/vmm.h"
|
||||
|
||||
#define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode.
|
||||
|
@ -38,5 +39,8 @@ extern sched_process *proc_list;
|
|||
void sched_init();
|
||||
sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
|
||||
uint32_t flags);
|
||||
|
||||
sched_process *sched_from_program(program_t *prog);
|
||||
|
||||
void sched_exit(int exit_code);
|
||||
void schedule(registers_t *regs);
|
|
@ -14,7 +14,7 @@ extern void __x86_64_syscall_init();
|
|||
static uint64_t __syscall_undefined() { return 0; }
|
||||
|
||||
void syscall_handle(registers_t *regs) {
|
||||
if (regs->rax > 1024) {
|
||||
if (regs->rax >= 1024) {
|
||||
log("syscall - syscall_handle was called with rax better than what Soaplin "
|
||||
"supports (1024). did you forget to set rax?\n");
|
||||
return;
|
||||
|
@ -50,13 +50,15 @@ void syscall_register(int id, syscall handler) {
|
|||
log("syscall - System call %d has been set to %p\n", id, handler);
|
||||
}
|
||||
|
||||
extern void syscall_write(int fd, const char *buf, size_t count);
|
||||
extern void syscall_exit(int exit_code);
|
||||
|
||||
void syscall_init() {
|
||||
for (int i = 0; i < 1024; i++)
|
||||
syscall_table[i] = (syscall)__syscall_undefined;
|
||||
|
||||
syscall_register(0, (syscall)syscall_exit);
|
||||
syscall_register(1, (syscall)syscall_write);
|
||||
syscall_register(60, (syscall)syscall_exit);
|
||||
|
||||
__x86_64_syscall_init();
|
||||
}
|
11
kernel/src/sys/syscalls/syscalls_fs.c
Normal file
11
kernel/src/sys/syscalls/syscalls_fs.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <stddef.h>
|
||||
#include <sys/printf.h>
|
||||
|
||||
int syscall_write(int fd, const char *buf, size_t count) {
|
||||
if (fd == 1) {
|
||||
printf("%s", buf); // Prevent the buffer from being formatted.
|
||||
return count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
|
@ -1,9 +1,18 @@
|
|||
bits 64
|
||||
|
||||
section .text
|
||||
global _start
|
||||
|
||||
_start:
|
||||
mov rax, 1025
|
||||
mov rax, 1 ; write syscall number
|
||||
mov rdi, 1 ; stdout file descriptor
|
||||
mov rsi, msg ; pointer to message
|
||||
mov rdx, msg_len ; message length
|
||||
syscall
|
||||
|
||||
.loop:
|
||||
jmp .loop
|
||||
jmp .loop
|
||||
|
||||
section .data
|
||||
msg db "Hello, World. Technically, this should work on both Soaplin & Linux.", 10 ; 10 is newline
|
||||
msg_len equ $ - msg
|
BIN
testing/test.o
BIN
testing/test.o
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue