aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-09-14 21:30:11 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-09-14 21:30:11 +0300
commitcabbf335824db0df835e4c541c19d3803ce38454 (patch)
treee7397d2b6637545b8e18f26135e3ad2a0a2fbe1e /common
parent025778e89e7d0fe3cd1ad53537c9cc6f3cd819cc (diff)
downloadkmi-cabbf335824db0df835e4c541c19d3803ce38454.tar.gz
kmi-cabbf335824db0df835e4c541c19d3803ce38454.zip
add canary to kernel stack
Diffstat (limited to 'common')
-rw-r--r--common/canary.c39
-rw-r--r--common/tcb.c12
-rw-r--r--common/uapi/dispatch.c21
3 files changed, 64 insertions, 8 deletions
diff --git a/common/canary.c b/common/canary.c
new file mode 100644
index 0000000..9fd89ff
--- /dev/null
+++ b/common/canary.c
@@ -0,0 +1,39 @@
+#include <apos/canary.h>
+#include <apos/mem.h>
+
+/**
+ * @file canary.c
+ * Kernel stack canary implementation.
+ */
+
+/** Typedef for canary value type. */
+typedef uint32_t canary_t;
+
+/** Canary magic value. */
+static const canary_t canary = 0xb00b1e5;
+
+/**
+ * Helper for calculating the canary location of \p t.
+ *
+ * @param t \ref tcb to calculate canary position of.
+ * @return Pointer to canary location, that is bottom of stack.
+ * \todo This assumes that all stacks grow downwards. Unlikely to ever be
+ * ported to a platform that doesn't abide by this, but keep it in mind anyway.
+ */
+static canary_t *get_canary(struct tcb *t)
+{
+ size_t s = order_size(KERNEL_STACK_PAGE_ORDER);
+ return (canary_t *)align_down((uintptr_t)t, s);
+}
+
+void set_canary(struct tcb *t)
+{
+ canary_t *c = get_canary(t);
+ *c = canary;
+}
+
+bool check_canary(struct tcb *t)
+{
+ canary_t *c = get_canary(t);
+ return *c != canary;
+}
diff --git a/common/tcb.c b/common/tcb.c
index 1e25f47..9768eb0 100644
--- a/common/tcb.c
+++ b/common/tcb.c
@@ -7,7 +7,6 @@
*/
#include <apos/tcb.h>
-#include <arch/cpu.h>
#include <apos/mem.h>
#include <apos/conf.h>
#include <apos/pmem.h>
@@ -16,6 +15,9 @@
#include <apos/types.h>
#include <apos/assert.h>
#include <apos/string.h>
+#include <apos/canary.h>
+
+#include <arch/cpu.h>
#include <arch/vmem.h>
/* arguably exessively many globals... */
@@ -137,7 +139,7 @@ struct tcb *create_thread(struct tcb *p)
{
hard_assert(tcbs, 0);
- vm_t bottom = alloc_page(MM_O0, 0);
+ vm_t bottom = alloc_page(KERNEL_STACK_PAGE_ORDER, 0);
/* move tcb to top of kernel stack, keeping alignment in check
* (hopefully) */
/** \todo check alignment */
@@ -163,6 +165,7 @@ struct tcb *create_thread(struct tcb *p)
t->rid = p->rid;
t->rpc.vmem = create_vmem();
+ set_canary(t);
return t;
}
@@ -303,8 +306,9 @@ struct tcb *cur_proc()
void use_tcb(struct tcb *t)
{
- t->cpu_id = cpu_id();
- cpu_tcb[cpu_id()] = t;
+ id_t cpu = cpu_id();
+ t->cpu_id = cpu;
+ cpu_tcb[cpu] = t;
}
struct tcb *get_tcb(id_t tid)
diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c
index c2ddbcf..73e037a 100644
--- a/common/uapi/dispatch.c
+++ b/common/uapi/dispatch.c
@@ -6,6 +6,7 @@
* Syscall dispatch.
*/
+#include <apos/canary.h>
#include <apos/debug.h>
#include <apos/uapi.h>
@@ -57,11 +58,23 @@ SYSCALL_DEFINE0(noop)(){
struct sys_ret syscall_dispatch(sys_arg_t syscall, sys_arg_t a, sys_arg_t b,
sys_arg_t c, sys_arg_t d)
{
- /** \todo Add check that syscall is not larger than table */
- sys_t call = syscall_table[syscall];
+ struct tcb *t = cur_tcb();
- if (!call)
+ size_t sc = syscall;
+ if (sc >= ARRAY_SIZE(syscall_table)) {
+ error("Syscall %zu outside allowed range [0 - %zu]\n", sc,
+ ARRAY_SIZE(syscall_table));
return (struct sys_ret){ ERR_INVAL, 0 };
+ }
- return call(a, b, c, d);
+ /* the syscall must be a valid number, as they're numbered in a linear
+ * fashion */
+ struct sys_ret r = syscall_table[syscall](a, b, c, d);
+
+ if (check_canary(t)) {
+ bug("Syscall %zu overwrote stack canary\n", syscall);
+ return (struct sys_ret){ ERR_INT, 0 };
+ }
+
+ return r;
}