Compare commits
2 Commits
7fb2807d0c
...
7e377ef712
Author | SHA1 | Date | |
---|---|---|---|
7e377ef712 | |||
29bd8a69fa |
16
apps/app.c
16
apps/app.c
@ -4,24 +4,18 @@
|
|||||||
|
|
||||||
void bye()
|
void bye()
|
||||||
{
|
{
|
||||||
console_print("byeee!\n");
|
printf("byeee!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
atexit(bye);
|
atexit(bye);
|
||||||
|
printf("Welcome to %s!\n", "Luna");
|
||||||
char buffer[64];
|
|
||||||
snprintf(buffer, sizeof(buffer), "Welcome to %s!\n", "Luna");
|
|
||||||
|
|
||||||
console_print(buffer);
|
|
||||||
|
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
snprintf(buffer, sizeof(buffer), "Realtime clock: %ld s\n", now);
|
printf("Realtime clock: %ld s\n", now);
|
||||||
|
|
||||||
console_print(buffer);
|
for (int i = 0; i < atoi("8"); i++) { console_write(".", 1); }
|
||||||
|
|
||||||
for (int i = 0; i < atoi("8"); i++) { console_print("."); }
|
console_write("\n", 1);
|
||||||
|
|
||||||
console_print("\n");
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ set(SOURCES
|
|||||||
src/thread/Scheduler.cpp
|
src/thread/Scheduler.cpp
|
||||||
src/sys/Syscall.cpp
|
src/sys/Syscall.cpp
|
||||||
src/sys/exit.cpp
|
src/sys/exit.cpp
|
||||||
src/sys/console_print.cpp
|
src/sys/console_write.cpp
|
||||||
src/sys/clock_gettime.cpp
|
src/sys/clock_gettime.cpp
|
||||||
src/InitRD.cpp
|
src/InitRD.cpp
|
||||||
src/ELF.cpp
|
src/ELF.cpp
|
||||||
|
@ -347,23 +347,74 @@ namespace MemoryManager
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Replace this with some kind of strdup_from_user() function.
|
bool validate_user_readable_page(u64 address)
|
||||||
|
{
|
||||||
|
auto rc = MMU::get_flags(address);
|
||||||
|
if (rc.has_error()) return false;
|
||||||
|
if (rc.value() & MMU::User) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validate_user_writable_page(u64 address)
|
||||||
|
{
|
||||||
|
auto rc = MMU::get_flags(address);
|
||||||
|
if (rc.has_error()) return false;
|
||||||
|
if ((rc.value() & MMU::User) && (rc.value() && MMU::ReadWrite)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool validate_userspace_string(u64 address)
|
bool validate_userspace_string(u64 address)
|
||||||
{
|
{
|
||||||
if (!validate_readable_page(address)) return false;
|
if (!validate_user_readable_page(address)) return false;
|
||||||
|
|
||||||
while (*(char*)address != 0)
|
while (*(char*)address != 0)
|
||||||
{
|
{
|
||||||
address++;
|
address++;
|
||||||
if (address % ARCH_PAGE_SIZE)
|
if (address % ARCH_PAGE_SIZE)
|
||||||
{
|
{
|
||||||
if (!validate_readable_page(address)) return false;
|
if (!validate_user_readable_page(address)) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool validate_user_write(void* user, usize size)
|
||||||
|
{
|
||||||
|
uintptr_t user_ptr = (uintptr_t)user;
|
||||||
|
uintptr_t user_page = align_down<ARCH_PAGE_SIZE>(user_ptr);
|
||||||
|
|
||||||
|
uintptr_t diff = user_ptr - user_page;
|
||||||
|
|
||||||
|
usize pages = get_blocks_from_size(size + diff, ARCH_PAGE_SIZE);
|
||||||
|
|
||||||
|
while (pages--)
|
||||||
|
{
|
||||||
|
if (!validate_user_writable_page(user_page)) return false;
|
||||||
|
user_page += ARCH_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validate_user_read(const void* user, usize size)
|
||||||
|
{
|
||||||
|
uintptr_t user_ptr = (uintptr_t)user;
|
||||||
|
uintptr_t user_page = align_down<ARCH_PAGE_SIZE>(user_ptr);
|
||||||
|
|
||||||
|
uintptr_t diff = user_ptr - user_page;
|
||||||
|
|
||||||
|
usize pages = get_blocks_from_size(size + diff, ARCH_PAGE_SIZE);
|
||||||
|
|
||||||
|
while (pages--)
|
||||||
|
{
|
||||||
|
if (!validate_user_readable_page(user_page)) return false;
|
||||||
|
user_page += ARCH_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool copy_to_user(void* user, const void* kernel, usize size)
|
bool copy_to_user(void* user, const void* kernel, usize size)
|
||||||
{
|
{
|
||||||
uintptr_t user_ptr = (uintptr_t)user;
|
uintptr_t user_ptr = (uintptr_t)user;
|
||||||
@ -375,7 +426,7 @@ namespace MemoryManager
|
|||||||
if (user_ptr != user_page)
|
if (user_ptr != user_page)
|
||||||
{
|
{
|
||||||
// FIXME: Validate that this page is writable by the user, not just the kernel.
|
// FIXME: Validate that this page is writable by the user, not just the kernel.
|
||||||
if (!validate_writable_page(user_page)) return false;
|
if (!validate_user_writable_page(user_page)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (size--)
|
while (size--)
|
||||||
@ -383,7 +434,7 @@ namespace MemoryManager
|
|||||||
// Crossed a page boundary, gotta check the page tables again before touching any memory!!
|
// Crossed a page boundary, gotta check the page tables again before touching any memory!!
|
||||||
if (user_ptr % ARCH_PAGE_SIZE)
|
if (user_ptr % ARCH_PAGE_SIZE)
|
||||||
{
|
{
|
||||||
if (!validate_writable_page(user_ptr)) return false;
|
if (!validate_user_writable_page(user_ptr)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(char*)user_ptr = *kernel_ptr++;
|
*(char*)user_ptr = *kernel_ptr++;
|
||||||
|
@ -20,8 +20,24 @@ namespace MemoryManager
|
|||||||
bool validate_readable_page(u64 address);
|
bool validate_readable_page(u64 address);
|
||||||
bool validate_writable_page(u64 address);
|
bool validate_writable_page(u64 address);
|
||||||
|
|
||||||
|
bool validate_user_readable_page(u64 address);
|
||||||
|
bool validate_user_writable_page(u64 address);
|
||||||
|
|
||||||
bool validate_userspace_string(u64 address);
|
bool validate_userspace_string(u64 address);
|
||||||
|
|
||||||
|
bool validate_user_write(void* user, usize size);
|
||||||
|
bool validate_user_read(const void* user, usize size);
|
||||||
|
|
||||||
|
template <typename T> bool validate_user_write_typed(T* user)
|
||||||
|
{
|
||||||
|
return validate_user_write(user, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> bool validate_user_read_typed(const T* user)
|
||||||
|
{
|
||||||
|
return validate_user_read(user, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
bool copy_to_user(void* user, const void* kernel, usize size);
|
bool copy_to_user(void* user, const void* kernel, usize size);
|
||||||
|
|
||||||
template <typename T> bool copy_to_user_typed(T* user, const T* kernel)
|
template <typename T> bool copy_to_user_typed(T* user, const T* kernel)
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
#include "memory/MemoryManager.h"
|
|
||||||
#include "sys/Syscall.h"
|
|
||||||
#include "video/TextConsole.h"
|
|
||||||
|
|
||||||
Result<u64> sys_console_print(Registers*, SyscallArgs args)
|
|
||||||
{
|
|
||||||
if (!MemoryManager::validate_userspace_string(args[0])) return err(EFAULT);
|
|
||||||
|
|
||||||
TextConsole::print((char*)args[0]);
|
|
||||||
|
|
||||||
return { 0 };
|
|
||||||
}
|
|
15
kernel/src/sys/console_write.cpp
Normal file
15
kernel/src/sys/console_write.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "memory/MemoryManager.h"
|
||||||
|
#include "sys/Syscall.h"
|
||||||
|
#include "video/TextConsole.h"
|
||||||
|
|
||||||
|
Result<u64> sys_console_write(Registers*, SyscallArgs args)
|
||||||
|
{
|
||||||
|
char* ptr = (char*)args[0];
|
||||||
|
usize size = (usize)args[1];
|
||||||
|
|
||||||
|
if (!MemoryManager::validate_user_read(ptr, size)) return err(EFAULT);
|
||||||
|
|
||||||
|
while (size--) { TextConsole::putchar(*ptr++); }
|
||||||
|
|
||||||
|
return { 0 };
|
||||||
|
}
|
@ -49,8 +49,14 @@ extern "C"
|
|||||||
/* Write up to max bytes of formatted output into a buffer. */
|
/* Write up to max bytes of formatted output into a buffer. */
|
||||||
int vsnprintf(char*, size_t, const char*, va_list);
|
int vsnprintf(char*, size_t, const char*, va_list);
|
||||||
|
|
||||||
|
/* Write formatted output to standard output. */
|
||||||
|
int printf(const char*, ...);
|
||||||
|
|
||||||
|
/* Write a string followed by a newline to standard output. */
|
||||||
|
int puts(const char* s);
|
||||||
|
|
||||||
/* Output a message to the console. */
|
/* Output a message to the console. */
|
||||||
int console_print(const char* msg);
|
int console_write(const char* msg, size_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <bits/errno-return.h>
|
#include <bits/errno-return.h>
|
||||||
#include <luna/Format.h>
|
#include <luna/Format.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -9,9 +10,9 @@ FILE* stderr = nullptr;
|
|||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
int console_print(const char* str)
|
int console_write(const char* str, size_t size)
|
||||||
{
|
{
|
||||||
long rc = syscall(SYS_console_print, str);
|
long rc = syscall(SYS_console_write, str, size);
|
||||||
__errno_return(rc, int);
|
__errno_return(rc, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,4 +49,25 @@ extern "C"
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int printf(const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
|
||||||
|
int rc = (int)pure_cstyle_format(
|
||||||
|
format, [](char c, void*) { console_write(&c, 1); }, nullptr, ap);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int puts(const char* s)
|
||||||
|
{
|
||||||
|
if (console_write(s, strlen(s)) < 0) return -1;
|
||||||
|
if (console_write("\n", 1) < 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define enumerate_syscalls(_e) _e(exit) _e(console_print) _e(clock_gettime)
|
#define enumerate_syscalls(_e) _e(exit) _e(console_write) _e(clock_gettime)
|
||||||
|
|
||||||
enum Syscalls
|
enum Syscalls
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user