mirror of
https://github.com/drasko/codezero.git
synced 2026-10-14 22:47:01 +02:00
Simplified cap id finding and destroying it.
It is not very straightforward to reach a capabilities list. We now use a single function to find out a capability by its id and its list, since the two are used frequently together (i.e. cap removal and destruction)
This commit is contained in:
@@ -146,9 +146,7 @@ struct capability *capability_find_by_rtype(struct ktcb *task,
|
|||||||
|
|
||||||
struct capability *cap_list_find_by_rtype(struct cap_list *clist,
|
struct capability *cap_list_find_by_rtype(struct cap_list *clist,
|
||||||
unsigned int rtype);
|
unsigned int rtype);
|
||||||
struct capability *cap_find_byid(l4id_t capid);
|
struct capability *cap_find_by_capid(l4id_t capid, struct cap_list **clist);
|
||||||
|
|
||||||
int cap_find_destroy(l4id_t capid);
|
|
||||||
|
|
||||||
/* Capability checking on system calls */
|
/* Capability checking on system calls */
|
||||||
int cap_map_check(struct ktcb *task, unsigned long phys, unsigned long virt,
|
int cap_map_check(struct ktcb *task, unsigned long phys, unsigned long virt,
|
||||||
|
|||||||
+16
-9
@@ -61,15 +61,16 @@ int cap_read_all(struct capability *caparray)
|
|||||||
int cap_share_single(l4id_t capid)
|
int cap_share_single(l4id_t capid)
|
||||||
{
|
{
|
||||||
struct capability *cap;
|
struct capability *cap;
|
||||||
|
struct cap_list *clist;
|
||||||
|
|
||||||
if (!(cap = cap_find_byid(capid)))
|
if (!(cap = cap_find_by_capid(capid, &clist)))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
if (cap->owner != current->tid)
|
if (cap->owner != current->tid)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
/* First remove it from its list */
|
/* First remove it from its list */
|
||||||
list_remove(&cap->list);
|
cap_list_remove(cap, clist);
|
||||||
|
|
||||||
/* Place it where it is shared */
|
/* Place it where it is shared */
|
||||||
cap_list_insert(cap, &curcont->cap_list);
|
cap_list_insert(cap, &curcont->cap_list);
|
||||||
@@ -145,9 +146,10 @@ out_err:
|
|||||||
int cap_grant_single(struct capability *req, unsigned int flags)
|
int cap_grant_single(struct capability *req, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct capability *cap;
|
struct capability *cap;
|
||||||
|
struct cap_list *clist;
|
||||||
struct ktcb *target;
|
struct ktcb *target;
|
||||||
|
|
||||||
if (!(cap = cap_find_byid(req->capid)))
|
if (!(cap = cap_find_by_capid(req->capid, &clist)))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
if (!(target = tcb_find(req->owner)))
|
if (!(target = tcb_find(req->owner)))
|
||||||
@@ -161,7 +163,7 @@ int cap_grant_single(struct capability *req, unsigned int flags)
|
|||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
/* First remove it from its list */
|
/* First remove it from its list */
|
||||||
list_remove(&cap->list);
|
cap_list_remove(cap, clist);
|
||||||
|
|
||||||
/* Change ownership */
|
/* Change ownership */
|
||||||
cap->owner = target->tid;
|
cap->owner = target->tid;
|
||||||
@@ -272,10 +274,11 @@ int cap_deduce_rtype(struct capability *orig, struct capability *new)
|
|||||||
int cap_deduce(struct capability *new)
|
int cap_deduce(struct capability *new)
|
||||||
{
|
{
|
||||||
struct capability *orig;
|
struct capability *orig;
|
||||||
|
struct cap_list *clist;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Find original capability */
|
/* Find original capability */
|
||||||
if (!(orig = cap_find_byid(new->capid)))
|
if (!(orig = cap_find_by_capid(new->capid, &clist)))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
/* Check that caller is owner */
|
/* Check that caller is owner */
|
||||||
@@ -353,9 +356,10 @@ int cap_deduce(struct capability *new)
|
|||||||
int cap_destroy(struct capability *cap)
|
int cap_destroy(struct capability *cap)
|
||||||
{
|
{
|
||||||
struct capability *orig;
|
struct capability *orig;
|
||||||
|
struct cap_list *clist;
|
||||||
|
|
||||||
/* Find original capability */
|
/* Find original capability */
|
||||||
if (!(orig = cap_find_byid(cap->capid)))
|
if (!(orig = cap_find_by_capid(cap->capid, &clist)))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
/* Check that caller is owner */
|
/* Check that caller is owner */
|
||||||
@@ -366,7 +370,8 @@ int cap_destroy(struct capability *cap)
|
|||||||
if (!(cap_generic_perms(orig) & CAP_CHANGEABLE))
|
if (!(cap_generic_perms(orig) & CAP_CHANGEABLE))
|
||||||
return -ENOCAP;
|
return -ENOCAP;
|
||||||
|
|
||||||
cap_find_destroy(cap->capid);
|
cap_list_remove(orig, clist);
|
||||||
|
free_capability(orig);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,10 +404,11 @@ static inline int cap_has_range(struct capability *c)
|
|||||||
int cap_split(struct capability *diff, unsigned int flags)
|
int cap_split(struct capability *diff, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct capability *orig, *new;
|
struct capability *orig, *new;
|
||||||
|
struct cap_list *clist;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Find original capability */
|
/* Find original capability */
|
||||||
if (!(orig = cap_find_byid(diff->capid)))
|
if (!(orig = cap_find_by_capid(diff->capid, &clist)))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
/* Check target type/resid/owner is the same */
|
/* Check target type/resid/owner is the same */
|
||||||
@@ -576,9 +582,10 @@ out_err:
|
|||||||
int cap_replicate(struct capability *dupl)
|
int cap_replicate(struct capability *dupl)
|
||||||
{
|
{
|
||||||
struct capability *new, *orig;
|
struct capability *new, *orig;
|
||||||
|
struct cap_list *clist;
|
||||||
|
|
||||||
/* Find original capability */
|
/* Find original capability */
|
||||||
if (!(orig = cap_find_byid(dupl->capid)))
|
if (!(orig = cap_find_by_capid(dupl->capid, &clist)))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
/* Check that caller is owner */
|
/* Check that caller is owner */
|
||||||
|
|||||||
+10
-46
@@ -128,70 +128,35 @@ struct capability *capability_find_by_rtype(struct ktcb *task,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
struct capability *cap_find_by_capid(l4id_t capid, struct cap_list **cap_list)
|
||||||
* FIXME: Make these functions pass a match function to cap_find()
|
|
||||||
* and remove all duplication. Same goes for find_rtype.
|
|
||||||
*/
|
|
||||||
struct capability *cap_find_byid(l4id_t capid)
|
|
||||||
{
|
{
|
||||||
struct capability *cap;
|
struct capability *cap;
|
||||||
struct ktcb *task = current;
|
struct ktcb *task = current;
|
||||||
|
|
||||||
/* Search task's own list */
|
/* Search task's own list */
|
||||||
list_foreach_struct(cap, &task->cap_list.caps, list)
|
list_foreach_struct(cap, &task->cap_list.caps, list)
|
||||||
if (cap->capid == capid)
|
if (cap->capid == capid) {
|
||||||
|
*cap_list = &task->cap_list;
|
||||||
return cap;
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
/* Search space list */
|
/* Search space list */
|
||||||
list_foreach_struct(cap, &task->space->cap_list.caps, list)
|
list_foreach_struct(cap, &task->space->cap_list.caps, list)
|
||||||
if (cap->capid == capid)
|
if (cap->capid == capid) {
|
||||||
|
*cap_list = &task->space->cap_list;
|
||||||
return cap;
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
/* Search container list */
|
/* Search container list */
|
||||||
list_foreach_struct(cap, &task->container->cap_list.caps, list)
|
list_foreach_struct(cap, &task->container->cap_list.caps, list)
|
||||||
if (cap->capid == capid)
|
if (cap->capid == capid) {
|
||||||
|
*cap_list = &task->container->cap_list;
|
||||||
return cap;
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: Instead of destroying, use cap_find_byid match function's
|
|
||||||
* match_args to pass a pointer to the capability list, so the
|
|
||||||
* caller may destroy it
|
|
||||||
*/
|
|
||||||
int cap_find_destroy(l4id_t capid)
|
|
||||||
{
|
|
||||||
struct capability *cap;
|
|
||||||
struct ktcb *task = current;
|
|
||||||
|
|
||||||
/* Search task's own list */
|
|
||||||
list_foreach_struct(cap, &task->cap_list.caps, list)
|
|
||||||
if (cap->capid == capid) {
|
|
||||||
cap_list_remove(cap, &task->cap_list);
|
|
||||||
free_capability(cap);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search space list */
|
|
||||||
list_foreach_struct(cap, &task->space->cap_list.caps, list)
|
|
||||||
if (cap->capid == capid) {
|
|
||||||
cap_list_remove(cap, &task->space->cap_list);
|
|
||||||
free_capability(cap);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search container list */
|
|
||||||
list_foreach_struct(cap, &task->container->cap_list.caps, list)
|
|
||||||
if (cap->capid == capid) {
|
|
||||||
cap_list_remove(cap, &task->container->cap_list);
|
|
||||||
free_capability(cap);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EEXIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct capability *(*cap_match_func_t) \
|
typedef struct capability *(*cap_match_func_t) \
|
||||||
(struct capability *cap, void *match_args);
|
(struct capability *cap, void *match_args);
|
||||||
|
|
||||||
@@ -543,7 +508,6 @@ struct capability *cap_match_thread(struct capability *cap,
|
|||||||
if (!(cap->access & CAP_TCTRL_WAIT))
|
if (!(cap->access & CAP_TCTRL_WAIT))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* We refuse to accept anything else */
|
/* We refuse to accept anything else */
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user