Commit 47d7e879 authored by Josh Kunz's avatar Josh Kunz

Fix cap_revoke to work on depth > 2 CDTs

The old algorithm would ignore 2nd-level children of the revoked node
because they were inserted "before" their parent that was getting
removed from the list.

The new algorithm re-starts the revoke from the last "checkpoint" (node
that is guaranteed to be in the output tree) so that we can detect the
children of deleted nodes.
parent 484e1ae7
......@@ -1040,13 +1040,13 @@ static int __cap_try_revoke(struct cnode *cnode, void * _args, void * callback_p
/* Note: This should do a depth-first traversal of the nodes, skipping any
* sub-trees that our `till_f` function tells us to skip. */
struct list_head * cur = cnode->children.next;
struct list_head * next = cur->next;
struct list_head * prev = &cnode->children;
struct list_head * cur = prev->next;
/* The tree lists are circular, so keep traversing the 'children' list
* until we reach the root again. We have to save the "next" ptr before
* we actually loop because 'cur' will become invalid if it gets removed
* from the tree. */
for (; &cnode->children != cur; cur = next, next = cur->next) {
for (; cur != &cnode->children; cur = prev->next) {
child = list_entry(cur, struct cnode, siblings);
/*
......@@ -1065,6 +1065,12 @@ static int __cap_try_revoke(struct cnode *cnode, void * _args, void * callback_p
CAP_BUG_ON(!__cap_cnode_is_used(child));
if (args->till_f(child, args->till_f_payload)) {
CAP_MSG("Skipping revoke on %#0lx because of till_f\n",
cptr_val(cap_cnode_cptr(child)));
/* This node is guarnteed to be in the output tree, so save it
* as the new "prev" */
prev = cur;
goto next_child;
}
......@@ -1084,6 +1090,10 @@ static int __cap_try_revoke(struct cnode *cnode, void * _args, void * callback_p
*/
__cap_cdt_remove_no_unlock(child);
/* If we remove a node, it may have spliced its children in before our
* next. So, re-start the traversal from the "next" of the previous node.
* This case is handled implicitly via the post condition of the for loop. */
/*
* Update microkernel state to reflect rights change
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment