diff options
author | dzwdz | 2022-04-12 19:44:38 +0200 |
---|---|---|
committer | dzwdz | 2022-04-12 19:44:38 +0200 |
commit | 008ac1574e127162f095a75f63c4c1be5d03b6d0 (patch) | |
tree | 23c7d249ec1e7b3ca85562a0e4a62a9221fb298c | |
parent | 75ec633805db108bfddb6454ff7f8d812475feaf (diff) |
kernel: make all sizes unsigned, sort out the sign mess
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/init/syscalls.c | 8 | ||||
-rw-r--r-- | src/kernel/proc.h | 2 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 7 | ||||
-rw-r--r-- | src/kernel/util.h | 6 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 4 | ||||
-rw-r--r-- | src/kernel/vfs/root.c | 19 | ||||
-rw-r--r-- | src/shared/syscalls.h | 8 |
8 files changed, 26 insertions, 30 deletions
@@ -3,7 +3,7 @@ PATH := $(shell pwd)/toolchain/bin/:$(PATH) AS = i686-elf-as CC = i686-elf-gcc CHECK = sparse -CFLAGS = -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wold-style-definition -Werror=implicit-function-declaration +CFLAGS += -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wold-style-definition -Werror=implicit-function-declaration -ftrack-macro-expansion=0 CFLAGS += -mgeneral-regs-only CFLAGS += -Isrc/ LFLAGS = -ffreestanding -O2 -nostdlib -lgcc diff --git a/src/init/syscalls.c b/src/init/syscalls.c index 99f68f3..15acd1c 100644 --- a/src/init/syscalls.c +++ b/src/init/syscalls.c @@ -22,12 +22,12 @@ int _syscall_mount(handle_t handle, const char __user *path, int len) { return _syscall(_SYSCALL_MOUNT, handle, (int)path, len, 0); } -int _syscall_read(handle_t handle, void __user *buf, int len, int offset) { - return _syscall(_SYSCALL_READ, handle, (int)buf, len, offset); +int _syscall_read(handle_t handle, void __user *buf, size_t len, int offset) { + return _syscall(_SYSCALL_READ, handle, (int)buf, (int)len, offset); } -int _syscall_write(handle_t handle, const void __user *buf, int len, int offset) { - return _syscall(_SYSCALL_WRITE, handle, (int)buf, len, offset); +int _syscall_write(handle_t handle, const void __user *buf, size_t len, int offset) { + return _syscall(_SYSCALL_WRITE, handle, (int)buf, (int)len, offset); } int _syscall_close(handle_t handle) { diff --git a/src/kernel/proc.h b/src/kernel/proc.h index dc7525d..d754522 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -34,7 +34,7 @@ struct process { } waits4fs; // PS_WAITS4FS struct { char __user *buf; - int max_len; + size_t max_len; struct fs_wait_response __user *res; } awaited_req; // PS_WAITS4REQUEST struct { diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 85db57a..dfd7dd4 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -125,7 +125,7 @@ fail: return -1; } -int _syscall_read(handle_t handle_num, void __user *buf, int len, int offset) { +int _syscall_read(handle_t handle_num, void __user *buf, size_t len, int offset) { struct handle *handle = &process_current->handles[handle_num]; if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1; if (handle->type != HANDLE_FILE) return -1; @@ -142,7 +142,7 @@ int _syscall_read(handle_t handle_num, void __user *buf, int len, int offset) { }); } -int _syscall_write(handle_t handle_num, const void __user *buf, int len, int offset) { +int _syscall_write(handle_t handle_num, const void __user *buf, size_t len, int offset) { struct handle *handle = &process_current->handles[handle_num]; if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1; if (handle->type != HANDLE_FILE) return -1; @@ -228,8 +228,7 @@ int _syscall_fs_respond(char __user *buf, int ret) { if (req->output.len > 0 && ret > 0) { // if this vfsop outputs data and ret is positive, it's the length of the buffer // TODO document - if (ret > req->output.len) - ret = req->output.len; // i'm not handling this in a special way - the fs server can prevent this on its own + ret = min(ret, capped_cast32(req->output.len)); if (!virt_cpy(req->caller->pages, req->output.buf, process_current->pages, buf, ret)) { // how should this error even be handled? TODO diff --git a/src/kernel/util.h b/src/kernel/util.h index 9b8cb3d..0e57d67 100644 --- a/src/kernel/util.h +++ b/src/kernel/util.h @@ -1,5 +1,6 @@ #pragma once #include <stddef.h> +#include <stdint.h> #define __NUM2STR(x) #x #define NUM2STR(x) __NUM2STR(x) @@ -13,3 +14,8 @@ typeof (a) _a = (a); \ typeof (b) _b = (b); \ _a > _b ? _a : _b; }) + +/* casts an uint32_t to int32_t, capping it at INT32_MAX instead of overflowing */ +static inline int32_t capped_cast32(uint32_t u) { + return (int32_t)min(u, (uint32_t)INT32_MAX); +} diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index 37b8c3a..151a066 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -26,11 +26,11 @@ struct vfs_request { char __user *buf; char *buf_kern; }; - int len; + size_t len; } input; struct { char __user *buf; - int len; + size_t len; } output; int id; // handle.file.id diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c index 2529b02..14f9a01 100644 --- a/src/kernel/vfs/root.c +++ b/src/kernel/vfs/root.c @@ -21,36 +21,28 @@ enum { }; static bool exacteq(struct vfs_request *req, const char *str) { - int len = strlen(str); + size_t len = strlen(str); assert(req->input.kern); return req->input.len == len && !memcmp(req->input.buf_kern, str, len); } /* truncates the length */ -static void req_preprocess(struct vfs_request *req, int max_len) { - // max_len is signed because req->*.len are signed too - // potential place for VULNs to occur - arbitrary kernel reads etc +static void req_preprocess(struct vfs_request *req, size_t max_len) { if (req->offset < 0) { // TODO negative offsets req->offset = 0; } - if (req->offset >= max_len) { + if (req->offset >= capped_cast32(max_len)) { req->input.len = 0; req->output.len = 0; req->offset = max_len; return; } - if (req->input.len < 0) req->input.len = 0; - if (req->output.len < 0) req->output.len = 0; - req->input.len = min(req->input.len, max_len - req->offset); req->output.len = min(req->output.len, max_len - req->offset); - assert(req->input.len >= 0); - assert(req->output.len >= 0); - assert(req->input.len + req->offset <= max_len); assert(req->input.len + req->offset <= max_len); } @@ -84,7 +76,6 @@ static int handle(struct vfs_request *req, bool *ready) { "com1\0" "ps2\0" "ata/"; - if (req->output.len < 0) return 0; // is this needed? TODO make that a size_t or something int len = min((size_t) req->output.len, sizeof(src)); virt_cpy_to(req->caller->pages, req->output.buf, src, len); return len; @@ -106,7 +97,7 @@ static int handle(struct vfs_request *req, bool *ready) { req->caller->waits4irq.ready = serial_ready; return -1; } - uint8_t buf[16]; + char buf[16]; size_t len = serial_read(buf, min(req->output.len, sizeof buf)); virt_cpy_to(req->caller->pages, req->output.buf, buf, len); return len; @@ -146,7 +137,7 @@ static int handle(struct vfs_request *req, bool *ready) { if (req->offset < 0) return 0; char buf[512]; uint32_t sector = req->offset / 512; - int len = min(req->output.len, 512 - (req->offset & 511)); + size_t len = min(req->output.len, 512 - ((size_t)req->offset & 511)); ata_read(req->id - HANDLE_ATA, sector, buf); virt_cpy_to(req->caller->pages, req->output.buf, buf, len); return len; diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h index 3e21b6c..9b250ab 100644 --- a/src/shared/syscalls.h +++ b/src/shared/syscalls.h @@ -43,16 +43,16 @@ int _syscall_fork(void); handle_t _syscall_open(const char __user *path, int len); int _syscall_mount(handle_t, const char __user *path, int len); -int _syscall_read(handle_t, void __user *buf, int len, int offset); -int _syscall_write(handle_t, const void __user *buf, int len, int offset); +int _syscall_read(handle_t, void __user *buf, size_t len, int offset); +int _syscall_write(handle_t, const void __user *buf, size_t len, int offset); int _syscall_close(handle_t); handle_t _syscall_fs_fork2(void); struct fs_wait_response { enum vfs_operation op; - int len; // how much was put in *buf - int capacity; // how much output can be accepted by the caller + size_t len; // how much was put in *buf + size_t capacity; // how much output can be accepted by the caller int id; // file id (returned by the open handler, passed to other calls) int offset; }; |