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; }