kernel: caps_mark_revoke: fix marking of cap copies for revoke
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 29 Aug 2017 13:38:00 +0000 (15:38 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 29 Aug 2017 14:26:38 +0000 (16:26 +0200)
Also add some comments explaining what the function is doing.

Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

kernel/cap_delete.c

index 556ceb8..6e9a810 100644 (file)
@@ -465,8 +465,14 @@ errval_t caps_mark_revoke(struct capability *base, struct cte *revoked)
     assert(base);
     assert(!revoked || revoked->mdbnode.owner == my_core_id);
 
+    // SG: In the following code, 'prev' is kind of a misnomer, this is all
+    // just contortions to iterate through all copies and descendants of a
+    // given capability. We update prev to be able to iterate through the tree
+    // even when we're going up and down the tree structure to find the next
+    // predecessor/successor.  -2017-08-29.
+
     // to avoid multiple mdb_find_greater, we store the predecessor of the
-    // current position
+    // current position.
     struct cte *prev = mdb_find_greater(base, true), *next = NULL;
     if (!prev || !(is_copy(base, &prev->cap)
                    || is_ancestor(&prev->cap, base)))
@@ -474,6 +480,24 @@ errval_t caps_mark_revoke(struct capability *base, struct cte *revoked)
         return SYS_ERR_CAP_NOT_FOUND;
     }
 
+    // Mark copies (backwards): we will never find descendants earlier in the
+    // ordering. However we might find copies!
+    for (next = mdb_predecessor(prev);
+         next && is_copy(base, &next->cap);
+         next = mdb_predecessor(prev))
+    {
+        if (next == revoked) {
+            // do not delete the revoked capability, use it as the new prev
+            // instead, and delete the old prev.
+            next = prev;
+            prev = revoked;
+        }
+        assert(revoked || next->mdbnode.owner != my_core_id);
+        caps_mark_revoke_copy(next);
+    }
+    // Mark copies (forward), use updated "prev". When we're done with this
+    // step next should be == revoked(?), and succ(next) should be the first
+    // descendant.
     for (next = mdb_successor(prev);
          next && is_copy(base, &next->cap);
          next = mdb_successor(prev))
@@ -489,6 +513,9 @@ errval_t caps_mark_revoke(struct capability *base, struct cte *revoked)
         caps_mark_revoke_copy(next);
     }
 
+    assert(prev == revoked);
+
+    // Mark descendants
     for (next = mdb_successor(prev);
          next && is_ancestor(&next->cap, base);
          next = mdb_successor(prev))