tests/misc: check sealed vs. local/global
diff --git a/tests/misc-test.cc b/tests/misc-test.cc index 2de724a..e39b1e5 100644 --- a/tests/misc-test.cc +++ b/tests/misc-test.cc
@@ -240,6 +240,46 @@ } } // namespace +void check_sealed_scoping() +{ + Capability<void> o{switcher_current_thread()}; + TEST(o.is_valid() && (o.type() == CheriSealTypeSealedTrustedStacks), + "Shared object cap not as expected: {}", + o); + + // Take the address of the o cap, requiring that it go out to memory. + Capability<Capability<void>> oP{&o}; + + /* + * Load a copy of our sealed o cap through an authority that lacks + * LoadGlobal permission. The result should be identical to the original + * but without global permission. + */ + Capability<Capability<void>> oPNoLoadGlobal = oP; + oPNoLoadGlobal.without_permissions(Permission::LoadGlobal); + const Capability<void> OLocal1 = *oPNoLoadGlobal; + + TEST(OLocal1.is_valid(), + "Loading global sealed cap through non-LoadGlobal invalid"); + TEST_EQUAL(OLocal1.type(), + o.type(), + "Loading global sealed cap through non-LoadGlobal bad type"); + TEST_EQUAL(OLocal1.permissions(), + o.permissions().without(Permission::Global), + "Loading global sealed cap through non-LoadGlobal bad perms"); + + /* + * Use CAndPerm to shed Global from our o cap. + * Spell this a little oddly to make sure we get CAndPerm with a mask of + * all 1s but Global. Using oLocal2.permissions().without() would do a + * cgetperm and then candperm. + */ + Capability<void> oLocal2 = o; + oLocal2.without_permissions(Permission::Global); + + TEST_EQUAL(oLocal2, OLocal1, "CAndPerm ~GL gone wrong"); +} + int test_misc() { check_timeouts(); @@ -247,6 +287,8 @@ check_memrchr(); check_pointer_utilities(); check_capability_set_inexact_at_most(); + check_sealed_scoping(); + debug_log("Testing shared objects."); check_shared_object("exampleK", SHARED_OBJECT(void, exampleK),