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.
This commit is contained in:
Bahadir Balban
2009-11-04 15:26:47 +02:00
parent b7e575817d
commit db57c598b0
5 changed files with 51 additions and 47 deletions

View File

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

View File

@@ -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)

View File

@@ -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),

View File

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

View File

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