From db57c598b082aa2f010d05925a6e675f4636eb64 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Wed, 4 Nov 2009 15:26:47 +0200 Subject: [PATCH 1/2] Merged MAP and VIRTMEM/PHYSMEM capabilities into one. VIRTMEM and PHYSMEM are theoretically separate resources to be protected than a MAP resource, which is meant to protect the syscall privileges. In practice MAP is always used together with a VIRTMEM and a PHYSMEM resource, therefore reach VIRTMEM/PHYSMEM resource is now merged with the MAP capability, combining the micro-permission bits. --- conts/test/src/capability.c | 14 ++++---- include/l4/generic/cap-types.h | 27 ++++++++-------- scripts/kernel/generate_kernel_cinfo.py | 4 +-- src/generic/capability.c | 43 ++++++++++++++----------- src/generic/resource.c | 10 +++--- 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/conts/test/src/capability.c b/conts/test/src/capability.c index f389d2e..44e1550 100644 --- a/conts/test/src/capability.c +++ b/conts/test/src/capability.c @@ -89,9 +89,13 @@ void cap_print(struct capability *cap) case CAP_TYPE_EXREGS: printf("Capability type:\t\t%s\n", "Exchange Registers"); break; - case CAP_TYPE_MAP: - printf("Capability type:\t\t%s\n", "Map"); + case CAP_TYPE_MAP_PHYSMEM: + printf("Capability type:\t\t%s\n", "Map/Physmem"); break; + case CAP_TYPE_MAP_VIRTMEM: + printf("Capability type:\t\t%s\n", "Map/Virtmem"); + break; + case CAP_TYPE_IPC: printf("Capability type:\t\t%s\n", "Ipc"); break; @@ -119,12 +123,6 @@ void cap_print(struct capability *cap) case CAP_RTYPE_CONTAINER: printf("Capability resource type:\t%s\n", "Container"); break; - case CAP_RTYPE_VIRTMEM: - printf("Capability resource type:\t%s\n", "Virtual Memory"); - break; - case CAP_RTYPE_PHYSMEM: - printf("Capability resource type:\t%s\n", "Physical Memory"); - break; case CAP_RTYPE_THREADPOOL: printf("Capability resource type:\t%s\n", "Thread Pool"); break; diff --git a/include/l4/generic/cap-types.h b/include/l4/generic/cap-types.h index d818acb..f4cbf33 100644 --- a/include/l4/generic/cap-types.h +++ b/include/l4/generic/cap-types.h @@ -12,12 +12,13 @@ #define CAP_TYPE_MASK 0x0000FFFF #define CAP_TYPE_TCTRL (1 << 0) #define CAP_TYPE_EXREGS (1 << 1) -#define CAP_TYPE_MAP (1 << 2) -#define CAP_TYPE_IPC (1 << 3) -#define CAP_TYPE_SCHED (1 << 4) -#define CAP_TYPE_UMUTEX (1 << 5) -#define CAP_TYPE_QUANTITY (1 << 6) -#define CAP_TYPE_CAP (1 << 7) +#define CAP_TYPE_MAP_PHYSMEM (1 << 2) +#define CAP_TYPE_MAP_VIRTMEM (1 << 3) +#define CAP_TYPE_IPC (1 << 4) +#define CAP_TYPE_SCHED (1 << 5) +#define CAP_TYPE_UMUTEX (1 << 6) +#define CAP_TYPE_QUANTITY (1 << 7) +#define CAP_TYPE_CAP (1 << 8) #define cap_type(c) ((c)->type & CAP_TYPE_MASK) /* @@ -29,14 +30,12 @@ #define CAP_RTYPE_SPACE (1 << 18) #define CAP_RTYPE_CONTAINER (1 << 19) #define CAP_RTYPE_PGGROUP (1 << 20) /* Group of paged threads */ -#define CAP_RTYPE_VIRTMEM (1 << 21) -#define CAP_RTYPE_PHYSMEM (1 << 22) -#define CAP_RTYPE_CPUPOOL (1 << 23) -#define CAP_RTYPE_THREADPOOL (1 << 24) -#define CAP_RTYPE_SPACEPOOL (1 << 25) -#define CAP_RTYPE_MUTEXPOOL (1 << 26) -#define CAP_RTYPE_MAPPOOL (1 << 27) /* For pmd spending */ -#define CAP_RTYPE_CAPPOOL (1 << 28) /* For new cap generation */ +#define CAP_RTYPE_CPUPOOL (1 << 21) +#define CAP_RTYPE_THREADPOOL (1 << 22) +#define CAP_RTYPE_SPACEPOOL (1 << 23) +#define CAP_RTYPE_MUTEXPOOL (1 << 24) +#define CAP_RTYPE_MAPPOOL (1 << 25) /* For pmd spending */ +#define CAP_RTYPE_CAPPOOL (1 << 26) /* For new cap generation */ #define cap_rtype(c) ((c)->type & CAP_RTYPE_MASK) diff --git a/scripts/kernel/generate_kernel_cinfo.py b/scripts/kernel/generate_kernel_cinfo.py index b0c8603..75fc914 100755 --- a/scripts/kernel/generate_kernel_cinfo.py +++ b/scripts/kernel/generate_kernel_cinfo.py @@ -76,7 +76,7 @@ pager_end = \ cap_virtmem = \ ''' \t\t\t[%(capidx)d] = { -\t\t\t\t.type = CAP_TYPE_MAP | CAP_RTYPE_VIRTMEM, +\t\t\t\t.type = CAP_TYPE_MAP_VIRTMEM | CAP_RTYPE_CONTAINER, \t\t\t\t.access = CAP_MAP_READ | CAP_MAP_WRITE | CAP_MAP_EXEC \t\t\t\t\t| CAP_MAP_CACHED | CAP_MAP_UNCACHED | CAP_MAP_UNMAP | CAP_MAP_UTCB, \t\t\t\t.start = __pfn(CONFIG_CONT%(cn)d_VIRT%(vn)d_START), @@ -88,7 +88,7 @@ cap_virtmem = \ cap_physmem = \ ''' \t\t\t[%(capidx)d] = { -\t\t\t\t.type = CAP_TYPE_MAP | CAP_RTYPE_PHYSMEM, +\t\t\t\t.type = CAP_TYPE_MAP_PHYSMEM | CAP_RTYPE_CONTAINER, \t\t\t\t.access = CAP_MAP_READ | CAP_MAP_WRITE | CAP_MAP_EXEC | \t\t\t\t\tCAP_MAP_CACHED | CAP_MAP_UNCACHED | CAP_MAP_UNMAP | CAP_MAP_UTCB, \t\t\t\t.start = __pfn(CONFIG_CONT%(cn)d_PHYS%(pn)d_START), diff --git a/src/generic/capability.c b/src/generic/capability.c index 6d58fd4..7722a50 100644 --- a/src/generic/capability.c +++ b/src/generic/capability.c @@ -499,7 +499,6 @@ struct sys_map_args { unsigned long virt; unsigned long npages; unsigned int flags; - unsigned int rtype; }; /* @@ -509,11 +508,12 @@ struct capability *cap_match_mem(struct capability *cap, void *args_ptr) { struct sys_map_args *args = args_ptr; + struct ktcb *target = args->task; unsigned long pfn; unsigned int perms; /* Set base according to what type of mem type we're matching */ - if (args->rtype == CAP_RTYPE_PHYSMEM) + if (cap_type(cap) == CAP_TYPE_MAP_PHYSMEM) pfn = __pfn(args->phys); else pfn = __pfn(args->virt); @@ -544,21 +544,28 @@ struct capability *cap_match_mem(struct capability *cap, return 0; } - return cap; - /* - * FIXME: - * - * Does it make sense to have a meaningful resid field - * in a memory resource? E.g. Which resources may I map it to? - * It might, as I can map an arbitrary mapping to an arbitrary - * thread in my container and break it's memory integrity. - * - * It seems it would be reasonable for a pager to have memory - * capabilities with a resid of its own id, and rtype of - * CAP_RTYPE_CONTAINER, effectively allowing it to do map - * operations on itself and its group of paged children. + * We have a target thread, check if capability match + * any resource fields in target */ + switch (cap_rtype(cap)) { + case CAP_RTYPE_THREAD: + if (target->tid != cap->resid) + return 0; + break; + case CAP_RTYPE_SPACE: + if (target->space->spid != cap->resid) + return 0; + break; + case CAP_RTYPE_CONTAINER: + if (target->container->cid != cap->resid) + return 0; + break; + default: + BUG(); /* Unknown cap type is a bug */ + } + + return cap; } #if defined(CONFIG_CAPABILITIES) @@ -603,14 +610,12 @@ int cap_map_check(struct ktcb *target, unsigned long phys, unsigned long virt, .flags = flags, }; - args.rtype = CAP_RTYPE_PHYSMEM; if (!(physmem = cap_find(current, cap_match_mem, - &args, CAP_TYPE_MAP))) + &args, CAP_TYPE_MAP_PHYSMEM))) return -ENOCAP; - args.rtype = CAP_RTYPE_VIRTMEM; if (!(virtmem = cap_find(current, cap_match_mem, - &args, CAP_TYPE_MAP))) + &args, CAP_TYPE_MAP_VIRTMEM))) return -ENOCAP; return 0; diff --git a/src/generic/resource.c b/src/generic/resource.c index cf85446..4ec4318 100644 --- a/src/generic/resource.c +++ b/src/generic/resource.c @@ -746,7 +746,7 @@ int process_cap_info(struct cap_info *cap, { int ret = 0; - switch (cap->type & CAP_RTYPE_MASK) { + switch (cap_rtype(cap)) { case CAP_RTYPE_THREADPOOL: bootres->nthreads += cap->size; break; @@ -768,8 +768,10 @@ int process_cap_info(struct cap_info *cap, /* Specifies how many new caps can be created */ bootres->ncaps += cap->size; break; + } - case CAP_RTYPE_VIRTMEM: + switch (cap_type(cap)) { + case CAP_TYPE_MAP_VIRTMEM: if ((ret = memcap_unmap(&kres->virtmem_free, cap->start, cap->end))) { if (ret < 0) @@ -787,7 +789,7 @@ int process_cap_info(struct cap_info *cap, } break; - case CAP_RTYPE_PHYSMEM: + case CAP_TYPE_MAP_PHYSMEM: if ((ret = memcap_unmap(&kres->physmem_free, cap->start, cap->end))) { if (ret < 0) @@ -804,8 +806,8 @@ int process_cap_info(struct cap_info *cap, BUG(); } break; - } + } return ret; } From aeef546544304933622034981296aaf5d0d27b52 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Wed, 4 Nov 2009 16:39:04 +0200 Subject: [PATCH 2/2] Changed l4id_t type to unsigned integer. Expanded task_ids to have cid Task ids are now unsigned as the container ids will need to be encoded in the id fields as well. For requests who require even more comprehensive id input, (such as thread creation) also added is the container id so that threads _could_ potentially be created in other containers as well. --- conts/libl4/include/l4lib/arch-arm/syscalls.h | 7 ++++--- conts/libl4/include/l4lib/arch-arm/types.h | 2 +- conts/posix/mm0/mm/init.c | 6 ++---- conts/posix/test0/main.c | 2 +- conts/posix/test0/src/test_exec/test_exec.c | 2 +- conts/test/main.c | 6 +++--- include/l4/api/ipc.h | 4 ++-- include/l4/arch/arm/types.h | 2 +- include/l4/generic/tcb.h | 12 +++++++++++- src/api/ipc.c | 7 +++++-- src/api/syscall.c | 1 + 11 files changed, 32 insertions(+), 19 deletions(-) diff --git a/conts/libl4/include/l4lib/arch-arm/syscalls.h b/conts/libl4/include/l4lib/arch-arm/syscalls.h index 09b1c62..584da7a 100644 --- a/conts/libl4/include/l4lib/arch-arm/syscalls.h +++ b/conts/libl4/include/l4lib/arch-arm/syscalls.h @@ -16,9 +16,10 @@ #include struct task_ids { - int tid; - int spid; - int tgid; + l4id_t tid; + l4id_t spid; + l4id_t tgid; + l4id_t cid; }; static inline void * diff --git a/conts/libl4/include/l4lib/arch-arm/types.h b/conts/libl4/include/l4lib/arch-arm/types.h index f01616b..76dc5ba 100644 --- a/conts/libl4/include/l4lib/arch-arm/types.h +++ b/conts/libl4/include/l4lib/arch-arm/types.h @@ -1,7 +1,7 @@ #ifndef __L4LIB_ARM_TYPES_H___ #define __L4LIB_ARM_TYPES_H__ -#define TASK_ID_INVALID -1 +#define TASK_ID_INVALID 0xFFFFFFFF #include diff --git a/conts/posix/mm0/mm/init.c b/conts/posix/mm0/mm/init.c index aa1eda8..51e65a6 100644 --- a/conts/posix/mm0/mm/init.c +++ b/conts/posix/mm0/mm/init.c @@ -226,13 +226,11 @@ int read_pager_capabilities() /* Set up pointers to important capabilities */ list_foreach_struct(cap, &capability_list.caps, list) { /* Physical memory bank */ - if ((cap->type & CAP_RTYPE_MASK) - == CAP_RTYPE_PHYSMEM) + if (cap_type(cap) == CAP_TYPE_MAP_PHYSMEM) cont_mem_regions.physmem = cap; /* Virtual regions */ - if ((cap->type & CAP_RTYPE_MASK) - == CAP_RTYPE_VIRTMEM) { + if (cap_type(cap) == CAP_TYPE_MAP_VIRTMEM) { /* Pager address region (get from linker-defined) */ if (__pfn_to_addr(cap->start) diff --git a/conts/posix/test0/main.c b/conts/posix/test0/main.c index eeba774..fdd97b9 100644 --- a/conts/posix/test0/main.c +++ b/conts/posix/test0/main.c @@ -26,7 +26,7 @@ void wait_pager(l4id_t partner) } pid_t parent_of_all; -pid_t pagerid; +l4id_t pagerid; int main(int argc, char *argv[]) { diff --git a/conts/posix/test0/src/test_exec/test_exec.c b/conts/posix/test0/src/test_exec/test_exec.c index 3eb42b2..41695a1 100644 --- a/conts/posix/test0/src/test_exec/test_exec.c +++ b/conts/posix/test0/src/test_exec/test_exec.c @@ -24,7 +24,7 @@ void wait_pager(l4id_t partner) // printf("Pager synced with us.\n"); } -pid_t pagerid; +l4id_t pagerid; int main(int argc, char *argv[]) { diff --git a/conts/test/main.c b/conts/test/main.c index 12ea2b7..aaa03ed 100644 --- a/conts/test/main.c +++ b/conts/test/main.c @@ -66,12 +66,12 @@ int main(void) printf("%s: Container %s started\n", __CONTAINER__, __CONTAINER_NAME__); - //capability_test(); + capability_test(); - exit_test(); + //exit_test(); /* Now quit to demo self-paging quit */ - l4_exit(0); + //l4_exit(0); /* Now quit by null pointer */ // *((int *)0) = 5; diff --git a/include/l4/api/ipc.h b/include/l4/api/ipc.h index 22be162..08ffedf 100644 --- a/include/l4/api/ipc.h +++ b/include/l4/api/ipc.h @@ -2,8 +2,8 @@ #define __IPC_H__ -#define L4_NILTHREAD -1 -#define L4_ANYTHREAD -2 +#define L4_NILTHREAD 0xFFFFFFFF +#define L4_ANYTHREAD 0xFFFFFFFE #define L4_IPC_TAG_MR_OFFSET 0 diff --git a/include/l4/arch/arm/types.h b/include/l4/arch/arm/types.h index 4c5df35..3106d6c 100644 --- a/include/l4/arch/arm/types.h +++ b/include/l4/arch/arm/types.h @@ -12,7 +12,7 @@ typedef signed short s16; typedef signed char s8; /* Thread/Space id type */ -typedef int l4id_t; +typedef unsigned int l4id_t; #endif /* !__ASSEMBLY__ */ #endif /* !__ARCH_TYPES_H__ */ diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index 4dceb95..ab707d0 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -39,11 +39,21 @@ enum task_state { TASK_DEAD = 3, }; -#define TASK_ID_INVALID -1 +#define TASK_CID_MASK 0xFF000000 +#define TASK_ID_MASK 0x00FFFFFF + +static inline int task_id_special(l4id_t id) +{ + /* Special ids have top 2 nibbles all set */ + return (id & TASK_CID_MASK) == TASK_CID_MASK; +} + +#define TASK_ID_INVALID 0xFFFFFFFF struct task_ids { l4id_t tid; l4id_t spid; l4id_t tgid; + l4id_t cid; }; struct container; diff --git a/src/api/ipc.c b/src/api/ipc.c index 0b99f19..020ee14 100644 --- a/src/api/ipc.c +++ b/src/api/ipc.c @@ -539,11 +539,14 @@ int sys_ipc(l4id_t to, l4id_t from, unsigned int flags) int ret = 0; /* Check arguments */ - if (from < L4_ANYTHREAD) { + if (task_id_special(from) && + from != L4_ANYTHREAD && from != L4_NILTHREAD) { ret = -EINVAL; goto error; } - if (to < L4_ANYTHREAD) { + + if (task_id_special(to) && + to != L4_ANYTHREAD && to != L4_NILTHREAD) { ret = -EINVAL; goto error; } diff --git a/src/api/syscall.c b/src/api/syscall.c index 1ff2769..94fea02 100644 --- a/src/api/syscall.c +++ b/src/api/syscall.c @@ -48,6 +48,7 @@ int sys_getid(struct task_ids *ids) ids->tid = this->tid; ids->spid = this->space->spid; ids->tgid = this->tgid; + ids->cid = this->container->cid; return 0; }