diff --git a/include/l4/api/capability.h b/include/l4/api/capability.h new file mode 100644 index 0000000..636d3f3 --- /dev/null +++ b/include/l4/api/capability.h @@ -0,0 +1,9 @@ +/* + * Syscall API for capability manipulation + * + * Copyright (C) 2009 Bahadir Balban + */ +#ifndef __API_CAPABILITY_H__ +#define __API_CAPABILITY_H__ + +#endif /* __API_CAPABILITY_H__ */ diff --git a/include/l4/api/kip.h b/include/l4/api/kip.h index 2110b36..52e3b85 100644 --- a/include/l4/api/kip.h +++ b/include/l4/api/kip.h @@ -46,7 +46,7 @@ struct kip { u8 api_version; u32 api_flags; - u32 kmem_control; + u32 container_control; u32 time; u32 space_control; @@ -54,7 +54,7 @@ struct kip { u32 ipc_control; u32 map; u32 ipc; - u32 kread; + u32 capability_control; u32 unmap; u32 exchange_registers; u32 thread_switch; @@ -83,10 +83,6 @@ struct kip { #define __VFSNAME__ "fs0" #define __BLKDEVNAME__ "blkdev0" -#define KDATA_PAGE_MAP 0 -#define KDATA_BOOTDESC 1 -#define KDATA_BOOTDESC_SIZE 2 - #if defined (__KERNEL__) extern struct kip kip; #endif /* __KERNEL__ */ diff --git a/include/l4/api/syscall.h b/include/l4/api/syscall.h index d001faa..b51189c 100644 --- a/include/l4/api/syscall.h +++ b/include/l4/api/syscall.h @@ -22,8 +22,8 @@ #define sys_ipc_control_offset 0x1C #define sys_map_offset 0x20 #define sys_getid_offset 0x24 -#define sys_kread_offset 0x28 -#define sys_kmem_control_offset 0x2C +#define sys_capability_control_offset 0x28 +#define sys_container_control_offset 0x2C #define sys_time_offset 0x30 #define sys_mutex_control_offset 0x34 #define syscalls_end_offset sys_mutex_control_offset @@ -42,8 +42,8 @@ int sys_ipc_control(void); int sys_map(unsigned long phys, unsigned long virt, unsigned long npages, unsigned long flags, unsigned int tid); int sys_getid(struct task_ids *ids); -int sys_kread(int rd, void *addr); -int sys_kmem_control(unsigned long pfn, int npages, int grant); +int sys_capability_control(unsigned int req, unsigned int flags, void *addr); +int sys_container_control(unsigned int req, unsigned int flags, void *addr); int sys_time(struct timeval *tv, int set); int sys_mutex_control(unsigned long mutex_address, int mutex_op); diff --git a/src/api/SConscript b/src/api/SConscript index b5f3252..71ca539 100644 --- a/src/api/SConscript +++ b/src/api/SConscript @@ -3,7 +3,7 @@ Import('env') Import('config_symbols') # The set of source files associated with this SConscript file. -src_local = ['kip.c', 'syscall.c', 'thread.c', 'ipc.c', 'space.c', 'mutex.c'] +src_local = ['kip.c', 'syscall.c', 'thread.c', 'ipc.c', 'space.c', 'mutex.c', 'capability.c'] obj = env.Object(src_local) diff --git a/src/api/capability.c b/src/api/capability.c new file mode 100644 index 0000000..ecac1d7 --- /dev/null +++ b/src/api/capability.c @@ -0,0 +1,57 @@ +/* + * Capability manipulation syscall. + * + * The heart of Codezero security + * mechanisms lay here. + * + * Copyright (C) 2009 Bahadir Balban + */ + +#include +#include +#include +#include +#include +#include INC_API(syscall.h) + + + +/* Error-checked kernel data request call */ +int __sys_capability_control(unsigned int req, unsigned int flags, void *userbuf) +{ + int err = 0; +#if 0 + switch(req) { + case KDATA_PAGE_MAP: + // printk("Handling KDATA_PAGE_MAP request.\n"); + if (check_access(vaddr, sizeof(page_map), MAP_USR_RW_FLAGS, 1) < 0) + return -EINVAL; + memcpy(dest, &page_map, sizeof(page_map)); + break; + case KDATA_BOOTDESC: + // printk("Handling KDATA_BOOTDESC request.\n"); + if (check_access(vaddr, bootdesc->desc_size, MAP_USR_RW_FLAGS, 1) < 0) + return -EINVAL; + memcpy(dest, bootdesc, bootdesc->desc_size); + break; + case KDATA_BOOTDESC_SIZE: + // printk("Handling KDATA_BOOTDESC_SIZE request.\n"); + if (check_access(vaddr, sizeof(unsigned int), MAP_USR_RW_FLAGS, 1) < 0) + return -EINVAL; + *(unsigned int *)dest = bootdesc->desc_size; + break; + + default: + printk("Unsupported kernel data request.\n"); + err = -1; + } +#endif + return err; + +} + +int sys_capability_control(unsigned int req, unsigned int flags, void *userbuf) +{ + return __sys_capability_control(req, flags, userbuf); +} + diff --git a/src/api/kip.c b/src/api/kip.c index 4fe3884..2487795 100644 --- a/src/api/kip.c +++ b/src/api/kip.c @@ -1,67 +1,9 @@ /* - * Kernel Interface Page and sys_kdata_read() + * Kernel Interface Page * * Copyright (C) 2007, 2008 Bahadir Balban */ -#include -#include -#include -#include #include INC_API(kip.h) -#include INC_API(syscall.h) -#include INC_GLUE(memlayout.h) -#include INC_ARCH(bootdesc.h) -__attribute__ ((section(".data.kip"))) struct kip kip; - -/* Error-checked kernel data request call */ -int __sys_kread(int rd, void *dest) -{ - int err = 0; - unsigned long vaddr = (unsigned long)dest; - - switch(rd) { - case KDATA_PAGE_MAP: - // printk("Handling KDATA_PAGE_MAP request.\n"); - if (check_access(vaddr, sizeof(page_map), MAP_USR_RW_FLAGS, 1) < 0) - return -EINVAL; - memcpy(dest, &page_map, sizeof(page_map)); - break; - case KDATA_BOOTDESC: - // printk("Handling KDATA_BOOTDESC request.\n"); - if (check_access(vaddr, bootdesc->desc_size, MAP_USR_RW_FLAGS, 1) < 0) - return -EINVAL; - memcpy(dest, bootdesc, bootdesc->desc_size); - break; - case KDATA_BOOTDESC_SIZE: - // printk("Handling KDATA_BOOTDESC_SIZE request.\n"); - if (check_access(vaddr, sizeof(unsigned int), MAP_USR_RW_FLAGS, 1) < 0) - return -EINVAL; - *(unsigned int *)dest = bootdesc->desc_size; - break; - - default: - printk("Unsupported kernel data request.\n"); - err = -1; - } - return err; - -} - -/* - * Privilaged tasks use this call to request data about the system during their - * initialisation. This read-like call is only available during system startup. - * It is much more flexible to use this method rather than advertise a customly - * forged KIP to all tasks throughout the system lifetime. Note, this does not - * support file positions, any such features aren't supported since this is call - * is discarded after startup. - */ -int sys_kread(int rd, void *addr) -{ - /* Error checking */ - if (rd < 0) - return -EINVAL; - - return __sys_kread(rd, addr); -} +SECTION(".data.kip") struct kip kip; diff --git a/src/api/syscall.c b/src/api/syscall.c index 243948e..cf7c79f 100644 --- a/src/api/syscall.c +++ b/src/api/syscall.c @@ -170,42 +170,8 @@ int sys_getid(struct task_ids *ids) return 0; } -/* - * Granted pages *must* be outside of the pages that are already owned and used - * by the kernel, otherwise a hostile/buggy pager can attack kernel addresses by - * fooling it to use them as freshly granted pages. Kernel owned pages are - * defined as, "any page that has been used by the kernel prior to all free - * physical memory is taken by a pager, and any other page that has been granted - * so far by any such pager." - */ -int validate_granted_pages(unsigned long pfn, int npages) +int sys_container_control(unsigned int req, unsigned int flags, void *userbuf) { - /* FIXME: Fill this in */ - return 0; -} - -/* - * Used by a pager to grant memory to kernel for its own use. Generally - * this memory is used for thread creation and memory mapping, (e.g. new - * page tables, page middle directories, per-task kernel stack etc.) - */ -int sys_kmem_control(unsigned long pfn, int npages, int grant) -{ - /* Pager is granting us pages */ - if (grant) { - /* - * Check if given set of pages are outside the pages already - * owned by the kernel. - */ - if (validate_granted_pages(pfn, npages) < 0) - return -EINVAL; - - /* Add the granted pages to the allocator */ - // if (pgalloc_add_new_grant(pfn, npages)) - BUG(); - } else /* Reclaim not implemented yet */ - BUG(); - return 0; } diff --git a/src/generic/container.c b/src/generic/container.c index 7693646..85a359a 100644 --- a/src/generic/container.c +++ b/src/generic/container.c @@ -32,7 +32,6 @@ struct container_info cinfo[] = { .type = CAP_TYPE_MAP | CAP_RTYPE_VIRTMEM, .access = CAP_MAP_READ | CAP_MAP_WRITE | CAP_MAP_EXEC | CAP_MAP_UNMAP, - .access = 0, .start = __pfn(0xE0000000), .end = __pfn(0xF0000000), .size = __pfn(0x10000000), @@ -49,7 +48,6 @@ struct container_info cinfo[] = { .type = CAP_TYPE_MAP | CAP_RTYPE_VIRTMEM, .access = CAP_MAP_READ | CAP_MAP_WRITE | CAP_MAP_EXEC | CAP_MAP_UNMAP, - .access = 0, .start = __pfn(0x20000000), .end = __pfn(0x30000000), .size = __pfn(0x10000000), diff --git a/src/glue/arm/systable.c b/src/glue/arm/systable.c index 805bef5..83a61ce 100644 --- a/src/glue/arm/systable.c +++ b/src/glue/arm/systable.c @@ -22,13 +22,13 @@ void kip_init_syscalls(void) kip.ipc_control = ARM_SYSCALL_PAGE + sys_ipc_control_offset; kip.map = ARM_SYSCALL_PAGE + sys_map_offset; kip.ipc = ARM_SYSCALL_PAGE + sys_ipc_offset; - kip.kread = ARM_SYSCALL_PAGE + sys_kread_offset; + kip.capability_control = ARM_SYSCALL_PAGE + sys_capability_control_offset; kip.unmap = ARM_SYSCALL_PAGE + sys_unmap_offset; kip.exchange_registers = ARM_SYSCALL_PAGE + sys_exchange_registers_offset; kip.thread_switch = ARM_SYSCALL_PAGE + sys_thread_switch_offset; kip.schedule = ARM_SYSCALL_PAGE + sys_schedule_offset; kip.getid = ARM_SYSCALL_PAGE + sys_getid_offset; - kip.kmem_control = ARM_SYSCALL_PAGE + sys_kmem_control_offset; + kip.container_control = ARM_SYSCALL_PAGE + sys_container_control_offset; kip.time = ARM_SYSCALL_PAGE + sys_time_offset; kip.mutex_control = ARM_SYSCALL_PAGE + sys_mutex_control_offset; } @@ -93,14 +93,18 @@ int arch_sys_map(syscall_context_t *regs) (unsigned int)regs->r4); } -int arch_sys_kread(syscall_context_t *regs) +int arch_sys_capability_control(syscall_context_t *regs) { - return sys_kread((int)regs->r0, (void *)regs->r1); + return sys_capability_control((unsigned int)regs->r0, + (unsigned int)regs->r1, + (void *)regs->r2); } -int arch_sys_kmem_control(syscall_context_t *regs) +int arch_sys_container_control(syscall_context_t *regs) { - return sys_kmem_control((unsigned long)regs->r0, (int)regs->r1, (int)regs->r2); + return sys_container_control((unsigned int)regs->r0, + (unsigned int)regs->r1, + (void *)regs->r2); } int arch_sys_time(syscall_context_t *regs) @@ -130,8 +134,8 @@ void syscall_init() syscall_table[sys_space_control_offset >> 2] = (syscall_fn_t)arch_sys_space_control; syscall_table[sys_ipc_control_offset >> 2] = (syscall_fn_t)arch_sys_ipc_control; syscall_table[sys_map_offset >> 2] = (syscall_fn_t)arch_sys_map; - syscall_table[sys_kread_offset >> 2] = (syscall_fn_t)arch_sys_kread; - syscall_table[sys_kmem_control_offset >> 2] = (syscall_fn_t)arch_sys_kmem_control; + syscall_table[sys_capability_control_offset >> 2] = (syscall_fn_t)arch_sys_capability_control; + syscall_table[sys_container_control_offset >> 2] = (syscall_fn_t)arch_sys_container_control; syscall_table[sys_time_offset >> 2] = (syscall_fn_t)arch_sys_time; syscall_table[sys_mutex_control_offset >> 2] = (syscall_fn_t)arch_sys_mutex_control;