Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ endif()
set (OUTPUT_DIR ${CMAKE_SOURCE_DIR}/out CACHE STRING "The output directory.")
set (OBOS_PAGE_REPLACEMENT_ALGORITHM "Aging" CACHE STRING "(Kernel developers only) The page replacement algorithm used by the MM.")
set (OBOS_DEV_PREFIX "/dev" CACHE STRING "Directory where the kernel places devices.")
set (OBOS_PERM_PREFIX "/sys/perm" CACHE STRING "Directory where the kernel checks for capabilities")
set (OBOS_CLANG_SUFFIX "" CACHE STRING "Some Linux distributions add a suffix to various clang and LLVM commands, such as the version used. Specify that suffix, if needed")

file (TO_CMAKE_PATH "${OUTPUT_DIR}" OUTPUT_DIR)
Expand Down Expand Up @@ -249,6 +250,7 @@ configure_file(${CMAKE_SOURCE_DIR}/src/inc/dev_prefix.h.in ${CMAKE_SOURCE_DIR}/s
add_compile_definitions(
OBOS_ARCHITECTURE_HAS_ACPI=${OBOS_ARCHITECTURE_HAS_ACPI}
OBOS_ARCHITECTURE_HAS_PCI=${OBOS_ARCHITECTURE_HAS_PCI}
OBOS_PERM_PREFIX="${OBOS_PERM_PREFIX}"
)

if (OBOS_USE_OBOS_GCC AND OBOS_COMPILE_USER_UTILS)
Expand Down
2 changes: 1 addition & 1 deletion src/oboskrnl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ list (APPEND oboskrnl_sources
"init_proc.c" "vfs/create.c" "net/route.c" "net/eth.c"
"net/ip.c" "net/arp.c" "power/event.c" "net/udp.c"
"net/icmp.c" "net/tcp.c" "vfs/socket.c" "net/lo.c"
"kinit.c" "vfs/local_socket.c"
"kinit.c" "vfs/local_socket.c" "perm.c"
)

add_executable(oboskrnl)
Expand Down
50 changes: 24 additions & 26 deletions src/oboskrnl/driver_interface/drv_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <handle.h>
#include <memmanip.h>
#include <syscall.h>
#include <perm.h>

#include <driver_interface/drv_sys.h>
#include <driver_interface/loader.h>
Expand All @@ -23,15 +24,11 @@
#include <allocators/base.h>

handle Sys_LoadDriver(const void* file, size_t szFile, obos_status* ustatus)
{
if (Core_GetCurrentThread()->proc->euid != ROOT_UID)
{
obos_status status = OBOS_STATUS_ACCESS_DENIED;
if (ustatus) memcpy_k_to_usr(ustatus, &status, sizeof(obos_status));
return HANDLE_INVALID;
}
{
obos_status status = OBOS_CapabilityCheck("drv/load", false);
if (obos_is_error(status))
return status;

obos_status status = OBOS_STATUS_SUCCESS;
if (!szFile)
{
status = OBOS_STATUS_INVALID_ARGUMENT;
Expand Down Expand Up @@ -62,19 +59,13 @@ handle Sys_LoadDriver(const void* file, size_t szFile, obos_status* ustatus)
return ret;
}

#define perm_check_impl(ret) do {\
if (Core_GetCurrentThread()->proc->euid != ROOT_UID)\
return (ret);\
} while(0)
#define perm_check() perm_check_impl(OBOS_STATUS_ACCESS_DENIED)
#define perm_check_hnd() perm_check_impl(HANDLE_INVALID)

obos_status Sys_StartDriver(handle driver, handle* mainThread)
{
perm_check();
obos_status status = OBOS_CapabilityCheck("drv/start", false);
if (obos_is_error(status))
return status;

OBOS_LockHandleTable(OBOS_CurrentHandleTable());
obos_status status = OBOS_STATUS_SUCCESS;
handle_desc* drv = OBOS_HandleLookup(OBOS_CurrentHandleTable(), driver, HANDLE_TYPE_DRIVER_ID, false, &status);
if (!drv)
{
Expand Down Expand Up @@ -105,10 +96,11 @@ obos_status Sys_StartDriver(handle driver, handle* mainThread)

obos_status Sys_UnloadDriver(handle driver)
{
perm_check();
obos_status status = OBOS_CapabilityCheck("drv/unload", false);
if (obos_is_error(status))
return status;

OBOS_LockHandleTable(OBOS_CurrentHandleTable());
obos_status status = OBOS_STATUS_SUCCESS;
handle_desc* drv = OBOS_HandleLookup(OBOS_CurrentHandleTable(), driver, HANDLE_TYPE_DRIVER_ID, false, &status);
if (!drv)
{
Expand All @@ -127,10 +119,11 @@ obos_status Sys_UnloadDriver(handle driver)

obos_status Sys_PnpLoadDriversAt(handle dent, bool wait)
{
perm_check();
obos_status status = OBOS_CapabilityCheck("drv/load-pnp", false);
if (obos_is_error(status))
return status;

OBOS_LockHandleTable(OBOS_CurrentHandleTable());
obos_status status = OBOS_STATUS_SUCCESS;
handle_desc* dirent = OBOS_HandleLookup(OBOS_CurrentHandleTable(), dent, HANDLE_TYPE_DIRENT, false, &status);
if (!dirent)
{
Expand All @@ -145,11 +138,13 @@ obos_status Sys_PnpLoadDriversAt(handle dent, bool wait)
// Finds a loaded driver by its name, and returns a handle to it.
handle Sys_FindDriverByName(const char* uname /* assumed to be 64-bytes at max */)
{
perm_check_hnd();
obos_status status = OBOS_CapabilityCheck("drv/open-name", false);
if (obos_is_error(status))
return HANDLE_INVALID;

char* name = nullptr;
size_t sz_name = 0;
obos_status status = OBOSH_ReadUserString(uname, nullptr, &sz_name);
status = OBOSH_ReadUserString(uname, nullptr, &sz_name);
if (obos_is_error(status))
return HANDLE_INVALID;
if (sz_name >= 64)
Expand Down Expand Up @@ -187,7 +182,9 @@ handle Sys_FindDriverByName(const char* uname /* assumed to be 64-bytes at max *
// If 'curr' is HANDLE_INVALID, the first item in the list is returned.
handle Sys_EnumerateLoadedDrivers(handle curr)
{
perm_check_hnd();
obos_status status = OBOS_CapabilityCheck("drv/enumerate", false);
if (obos_is_error(status))
return HANDLE_INVALID;

driver_id* id = nullptr;

Expand Down Expand Up @@ -222,13 +219,14 @@ handle Sys_EnumerateLoadedDrivers(handle curr)
// Queries the name of the driver in 'drv'.
obos_status Sys_QueryDriverName(handle driver, char* namebuf, size_t *sznamebuf /* need not be over 64 */)
{
perm_check();
obos_status status = OBOS_CapabilityCheck("drv/query-name", false);
if (obos_is_error(status))
return status;

if (!sznamebuf)
return OBOS_STATUS_INVALID_ARGUMENT;

OBOS_LockHandleTable(OBOS_CurrentHandleTable());
obos_status status = OBOS_STATUS_SUCCESS;
handle_desc* drv = OBOS_HandleLookup(OBOS_CurrentHandleTable(), driver, HANDLE_TYPE_DRIVER_ID, false, &status);
if (!drv)
{
Expand Down
45 changes: 43 additions & 2 deletions src/oboskrnl/mm/mm_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* Copyright (c) 2024-2025 Omar Berrow
*/

#include "mm/swap.h"
#include <int.h>
#include <memmanip.h>
#include <klog.h>
#include <perm.h>
#include <error.h>
#include <syscall.h>
#include <handle.h>
Expand All @@ -23,6 +23,7 @@
#include <mm/mm_sys.h>
#include <mm/disk_swap.h>
#include <mm/fork.h>
#include <mm/swap.h>

#include <vfs/dirent.h>

Expand Down Expand Up @@ -81,6 +82,16 @@ void* Sys_VirtualMemoryAlloc(handle ctx, void* base, size_t size, struct vma_all
prot &= ~OBOS_PROTECTION_CACHE_DISABLE;
flags &= ~VMA_FLAGS_32BITPHYS; // userspace doesn't need this as much as kernel mode

if (flags & VMA_FLAGS_NON_PAGED)
{
obos_status status = OBOS_CapabilityCheck("mm/allocate-non-paged", false);
if (obos_is_error(status))
{
if (pstatus) memcpy_k_to_usr(pstatus, &status, sizeof(status));
return nullptr;
}
}

void* ret = Mm_VirtualMemoryAllocEx(vmm_ctx, base, size, prot, flags, file, args.offset, &status);
if (pstatus)
memcpy_k_to_usr(pstatus, &status, sizeof(status));
Expand All @@ -99,10 +110,12 @@ obos_status Sys_VirtualMemoryProtect(handle ctx, void* base, size_t size, prot_f
}
obos_status Sys_VirtualMemoryLock(handle ctx, void* base, size_t size)
{
OBOS_UNUSED(ctx && base && size);
return OBOS_STATUS_UNIMPLEMENTED;
}
obos_status Sys_VirtualMemoryUnlock(handle ctx, void* base, size_t size)
{
OBOS_UNUSED(ctx && base && size);
return OBOS_STATUS_UNIMPLEMENTED;
}

Expand Down Expand Up @@ -157,6 +170,10 @@ size_t Sys_GetUsedPhysicalMemoryCount()

obos_status Sys_QueryPageInfo(handle ctx, void* base, page_info* info)
{
obos_status status = OBOS_CapabilityCheck("mm/query-page-info", false);
if (obos_is_error(status))
return status;

context* vmm_ctx = context_from_handle(ctx, false, 0, true);
// Search the page in the RB-Tree.
irql oldIrql = Core_SpinlockAcquire(&vmm_ctx->lock);
Expand Down Expand Up @@ -198,9 +215,13 @@ obos_status Sys_MakeDiskSwap(const char* upath)

obos_status Sys_SwitchSwap(const char* upath)
{
obos_status status = OBOS_CapabilityCheck("mm/switch-swap", false);
if (obos_is_error(status))
return status;

char* path = nullptr;
size_t sz_path = 0;
obos_status status = OBOSH_ReadUserString(upath, nullptr, &sz_path);
status = OBOSH_ReadUserString(upath, nullptr, &sz_path);
if (obos_is_error(status))
return status;
path = ZeroAllocate(OBOS_KernelAllocator, sz_path+1, sizeof(char), nullptr);
Expand Down Expand Up @@ -236,6 +257,26 @@ obos_status Sys_SwitchSwap(const char* upath)

void Sys_SyncAnonPages()
{
obos_status status = OBOS_CapabilityCheck("mm/sync-anon", true);
if (obos_is_error(status))
return;
Mm_PageWriterOperation = PAGE_WRITER_SYNC_ANON;
Mm_WakePageWriter(true);
}

handle Sys_MmFork()
{
// Zeroed in Mm_ConstructContext
context* ctx = Allocate(Mm_Allocator, sizeof(context), nullptr);
Mm_ConstructContext(ctx);
Mm_ForkContext(ctx, Core_GetCurrentThread()->proc->ctx);
ctx->workingSet.capacity = Core_GetCurrentThread()->proc->ctx->workingSet.capacity;

OBOS_LockHandleTable(OBOS_CurrentHandleTable());
handle_desc* desc = nullptr;
handle hnd = OBOS_HandleAllocate(OBOS_CurrentHandleTable(), HANDLE_TYPE_VMM_CONTEXT, &desc);
desc->un.vmm_context = ctx;
OBOS_UnlockHandleTable(OBOS_CurrentHandleTable());

return hnd;
}
2 changes: 2 additions & 0 deletions src/oboskrnl/mm/mm_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ obos_status Sys_QueryPageInfo(handle ctx, void* base, page_info* info);
obos_status Sys_MakeDiskSwap(const char* path);
obos_status Sys_SwitchSwap(const char* path);
void Sys_SyncAnonPages();

handle Sys_MmFork();
Loading