Skip to content

Commit d1ebe1e

Browse files
committed
Shared objects might want LoadGlobal permission
1 parent 8807ce6 commit d1ebe1e

File tree

9 files changed

+145
-81
lines changed

9 files changed

+145
-81
lines changed

sdk/core/allocator/alloc.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,8 @@ class MState
10261026
*/
10271027
[[nodiscard]] __always_inline auto hazard_list_begin()
10281028
{
1029-
auto *lockWord{SHARED_OBJECT(uint32_t, allocator_epoch)};
1029+
auto *lockWord{SHARED_OBJECT_WITH_DATA_PERMISSIONS(
1030+
uint32_t, allocator_epoch, true, true)};
10301031
uint32_t epoch = *lockWord >> 16;
10311032
Debug::Invariant(
10321033
(epoch & 1) == 0,
@@ -1276,9 +1277,14 @@ class MState
12761277
bool hazard_pointer_check(Capability<void> allocation)
12771278
{
12781279
// It is now safe to walk the hazard list.
1279-
Capability<void *> hazards =
1280-
const_cast<void **>(SHARED_OBJECT_WITH_PERMISSIONS(
1281-
void *, allocator_hazard_pointers, true, false, true, false));
1280+
Capability<void *> hazards = const_cast<void **>(
1281+
SHARED_OBJECT_WITH_PERMISSIONS(void *,
1282+
allocator_hazard_pointers,
1283+
true,
1284+
false,
1285+
true,
1286+
false,
1287+
false));
12821288
size_t pointers = hazards.length() / sizeof(void *);
12831289
for (size_t i = 0; i < pointers; i++)
12841290
{

sdk/core/allocator/main.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,13 @@ namespace
9999
Capability m{tbase.cast<MState>()};
100100

101101
size_t hazardQuarantineSize =
102-
Capability{
103-
SHARED_OBJECT_WITH_PERMISSIONS(
104-
void *, allocator_hazard_pointers, true, false, true, false)}
102+
Capability{SHARED_OBJECT_WITH_PERMISSIONS(void *,
103+
allocator_hazard_pointers,
104+
true,
105+
false,
106+
true,
107+
false,
108+
false)}
105109
.length();
106110

107111
m.bounds() = sizeof(*m);
@@ -128,13 +132,15 @@ namespace
128132
{
129133
if (gm == nullptr)
130134
{
135+
// Access without LoadGlobal to help ensure we don't break isolation
131136
Capability heap = const_cast<void *>(
132137
MMIO_CAPABILITY_WITH_PERMISSIONS(void,
133138
heap,
134139
/*load*/ true,
135140
/*store*/ true,
136141
/*capabilities*/ true,
137-
/*loadMutable*/ true));
142+
/*loadMutable*/ true,
143+
/*loadGlobal*/ false));
138144

139145
revoker.init();
140146
gm = mstate_init(heap, heap.bounds());

sdk/core/loader/types.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -875,12 +875,18 @@ namespace loader
875875
*/
876876
static constexpr size_t PermitLoadMutable = (1UL << 28);
877877

878+
/**
879+
* Bit in `sizeAndPermissions` indicating that this import has
880+
* load-global permission.
881+
*/
882+
static constexpr size_t PermitLoadGlobal = (1UL << 27);
883+
878884
/**
879885
* Mask for the used permissions.
880886
*/
881-
static constexpr size_t PermissionsMask = PermitLoad | PermitStore |
882-
PermitLoadStoreCapabilities |
883-
PermitLoadMutable;
887+
static constexpr size_t PermissionsMask =
888+
PermitLoad | PermitStore | PermitLoadStoreCapabilities |
889+
PermitLoadMutable | PermitLoadGlobal;
884890

885891
/**
886892
* Mask for the space reserved for permissions.
@@ -959,7 +965,8 @@ namespace loader
959965
Permission::Load,
960966
Permission::Store,
961967
Permission::LoadStoreCapability,
962-
Permission::LoadMutable};
968+
Permission::LoadMutable,
969+
Permission::LoadGlobal};
963970
CHERI::PermissionSet p{DefaultPermissions};
964971
if ((sizeAndPermissions & PermitLoad) == 0)
965972
{
@@ -977,6 +984,10 @@ namespace loader
977984
{
978985
p = p.without(Permission::LoadMutable);
979986
}
987+
if ((sizeAndPermissions & PermitLoadGlobal) == 0)
988+
{
989+
p = p.without(Permission::LoadGlobal);
990+
}
980991
return p;
981992
}
982993
};

sdk/include/compartment-macros.h

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
static const struct Perms \
1717
{ \
1818
bool permitLoad, permitStore, permitLoadStoreCapabilities, \
19-
permitLoadMutable; \
19+
permitLoadMutable, permitLoadGlobal; \
2020
} perms = {__VA_ARGS__}; \
2121
type *ret; /* NOLINT(bugprone-macro-parentheses) */ \
2222
__asm(".ifndef " mangledName "\n" \
@@ -38,7 +38,8 @@
3838
: "i"(((perms.permitLoad) ? (1 << 31) : 0) + \
3939
((perms.permitStore) ? (1 << 30) : 0) + \
4040
((perms.permitLoadStoreCapabilities) ? (1 << 29) : 0) + \
41-
((perms.permitLoadMutable) ? (1 << 28) : 0))); \
41+
((perms.permitLoadMutable) ? (1 << 28) : 0) + \
42+
((perms.permitLoadGlobal) ? (1 << 27) : 0))); \
4243
ret; \
4344
})
4445

@@ -48,8 +49,8 @@
4849
* can be used only in code (it cannot be used to initialise a global).
4950
*
5051
* The last arguments specify the set of permissions that this capability
51-
* holds: Load Data (LD), Store Data (SD), Memory Capabilities (MC), and Load
52-
* Mutable (LM).
52+
* holds: Load Data (LD), Store Data (SD), Memory Capabilities (MC), Load
53+
* Mutable (LM), and Load Global (LG).
5354
*
5455
* MMIO capabilities are always global (GL) and without store local (SL).
5556
*/
@@ -79,8 +80,8 @@
7980
* used to initialise a global).
8081
*
8182
* The last arguments specify the set of permissions that this capability
82-
* holds: Load Data (LD), Store Data (SD), Memory Capabilities (MC), and Load
83-
* Mutable (LM).
83+
* holds: Load Data (LD), Store Data (SD), Memory Capabilities (MC), Load
84+
* Mutable (LM), and Load Global (LG).
8485
*
8586
* Capabilities to pre-shared objects are always global (GL) and without store
8687
* local (SL).
@@ -103,7 +104,21 @@
103104
* To define a reduced set of permissions use `SHARED_OBJECT_WITH_PERMISSIONS`.
104105
*/
105106
#define SHARED_OBJECT(type, name) \
106-
SHARED_OBJECT_WITH_PERMISSIONS(type, name, true, true, true, true)
107+
SHARED_OBJECT_WITH_PERMISSIONS(type, name, true, true, true, true, true)
108+
109+
/**
110+
* Provide a capability of the type `type *` referring to the pre-shared object
111+
* with `name` as its name. This macro can be used only in code (it cannot be
112+
* used to initialise a global).
113+
*
114+
* Pre-shared object capabilities produced by this macro have the indicated load
115+
* and store permission, but no load/store-capability permissions (and,
116+
* therefore, no load-mutable or load-global permissions).
117+
*/
118+
#define SHARED_OBJECT_WITH_DATA_PERMISSIONS( \
119+
type, name, permitLoad, permitStore) \
120+
SHARED_OBJECT_WITH_PERMISSIONS( \
121+
type, name, permitLoad, permitStore, false, false, false)
107122

108123
/**
109124
* Macro to test whether a device with a specific name exists in the board

sdk/lib/compartment_helpers/claim_fast.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
int heap_claim_ephemeral(Timeout *timeout, const void *ptr, const void *ptr2)
1111
{
1212
void **hazards = switcher_thread_hazard_slots();
13-
auto *epochCounter{const_cast<
14-
cheriot::atomic<uint32_t> *>(SHARED_OBJECT_WITH_PERMISSIONS(
15-
cheriot::atomic<uint32_t>, allocator_epoch, true, false, false, false))};
13+
auto *epochCounter{const_cast<cheriot::atomic<uint32_t> *>(
14+
SHARED_OBJECT_WITH_DATA_PERMISSIONS(
15+
cheriot::atomic<uint32_t>, allocator_epoch, true, false))};
1616
uint32_t epoch = epochCounter->load();
1717
int values = 2;
1818
// Skip processing pointers that don't refer to heap memory.

tests.extra/regress-double_ref_shared/top1.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
void top1()
44
{
5-
auto ref1 =
6-
SHARED_OBJECT_WITH_PERMISSIONS(struct Foo, foo, true, true, false, false);
5+
auto ref1 = SHARED_OBJECT_WITH_DATA_PERMISSIONS(Foo, foo, true, true);
76

87
ref1->bar = 1;
98
}

tests.extra/regress-double_ref_shared/top2.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ using Debug = ConditionalDebug<true, "top2">;
66

77
void top2()
88
{
9-
auto ref2 = SHARED_OBJECT_WITH_PERMISSIONS(
10-
struct Foo, foo, true, false, false, false);
9+
auto ref2 = SHARED_OBJECT_WITH_DATA_PERMISSIONS(Foo, foo, true, false);
1110

1211
Debug::log("ref2: {}", ref2->bar);
1312
}

tests/misc-test.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,22 +381,30 @@ int test_misc()
381381
Permission::Load,
382382
Permission::Store,
383383
Permission::LoadStoreCapability,
384-
Permission::LoadMutable});
384+
Permission::LoadMutable,
385+
Permission::LoadGlobal});
385386
check_shared_object(
386387
"exampleK",
387-
SHARED_OBJECT_WITH_PERMISSIONS(void, exampleK, true, true, false, false),
388+
SHARED_OBJECT_WITH_PERMISSIONS(
389+
void, exampleK, true, true, false, false, false),
388390
1024,
389391
{Permission::Global, Permission::Load, Permission::Store});
390392
check_shared_object(
391393
"test_word",
392-
SHARED_OBJECT_WITH_PERMISSIONS(void, test_word, true, false, true, false),
394+
SHARED_OBJECT_WITH_PERMISSIONS(
395+
void, test_word, true, false, true, false, false),
393396
4,
394397
{Permission::Global, Permission::Load, Permission::LoadStoreCapability});
395398
check_shared_object("test_word",
396399
SHARED_OBJECT_WITH_PERMISSIONS(
397-
void, test_word, true, false, false, false),
400+
void, test_word, true, false, false, false, false),
398401
4,
399402
{Permission::Global, Permission::Load});
403+
check_shared_object(
404+
"test_word data",
405+
SHARED_OBJECT_WITH_DATA_PERMISSIONS(void, test_word, true, false),
406+
4,
407+
{Permission::Global, Permission::Load});
400408
check_odd_memcmp();
401409
TEST_EQUAL(strnlen(*volatileString, 3),
402410
3,

tests/mmio-test.cc

Lines changed: 71 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,66 +16,86 @@ void check_permissions(Capability<volatile void> mmio, PermissionSet p)
1616

1717
int test_mmio()
1818
{
19-
check_permissions(
20-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, false, false, false),
21-
{Permission::Global});
22-
check_permissions(
23-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, false, true, false),
24-
{Permission::Global});
25-
check_permissions(
26-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, false, false, true),
27-
{Permission::Global});
28-
check_permissions(
29-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, false, true, true),
30-
{Permission::Global});
31-
check_permissions(
32-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, true, false, false),
33-
{Permission::Global, Permission::Store});
34-
check_permissions(
35-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, true, true, false),
19+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
20+
Uart, uart, false, false, false, false, false),
21+
{Permission::Global});
22+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
23+
Uart, uart, false, false, true, false, false),
24+
{Permission::Global});
25+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
26+
Uart, uart, false, false, false, true, false),
27+
{Permission::Global});
28+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
29+
Uart, uart, false, false, true, true, false),
30+
{Permission::Global});
31+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
32+
Uart, uart, false, true, false, false, false),
33+
{Permission::Global, Permission::Store});
34+
check_permissions(
35+
MMIO_CAPABILITY_WITH_PERMISSIONS(
36+
Uart, uart, false, true, true, false, false),
3637
{Permission::Global, Permission::Store, Permission::LoadStoreCapability});
38+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
39+
Uart, uart, false, true, false, true, false),
40+
{Permission::Global, Permission::Store});
3741
check_permissions(
38-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, true, false, true),
39-
{Permission::Global, Permission::Store});
40-
check_permissions(
41-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, false, true, true, true),
42+
MMIO_CAPABILITY_WITH_PERMISSIONS(
43+
Uart, uart, false, true, true, true, false),
4244
{Permission::Global, Permission::Store, Permission::LoadStoreCapability});
45+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
46+
Uart, uart, true, false, false, false, false),
47+
{Permission::Global, Permission::Load});
4348
check_permissions(
44-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, false, false, false),
45-
{Permission::Global, Permission::Load});
46-
check_permissions(
47-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, false, true, false),
49+
MMIO_CAPABILITY_WITH_PERMISSIONS(
50+
Uart, uart, true, false, true, false, false),
4851
{Permission::Global, Permission::Load, Permission::LoadStoreCapability});
49-
check_permissions(
50-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, false, false, true),
51-
{Permission::Global, Permission::Load});
52-
check_permissions(
53-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, false, true, true),
54-
{Permission::Global,
55-
Permission::Load,
56-
Permission::LoadStoreCapability,
57-
Permission::LoadMutable});
58-
check_permissions(
59-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, true, false, false),
52+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
53+
Uart, uart, true, false, false, true, false),
54+
{Permission::Global, Permission::Load});
55+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
56+
Uart, uart, true, false, true, true, false),
57+
{Permission::Global,
58+
Permission::Load,
59+
Permission::LoadStoreCapability,
60+
Permission::LoadMutable});
61+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
62+
Uart, uart, true, false, true, true, true),
63+
{Permission::Global,
64+
Permission::Load,
65+
Permission::LoadStoreCapability,
66+
Permission::LoadMutable,
67+
Permission::LoadGlobal});
68+
check_permissions(
69+
MMIO_CAPABILITY_WITH_PERMISSIONS(
70+
Uart, uart, true, true, false, false, false),
6071
{Permission::Global, Permission::Load, Permission::Store});
6172
check_permissions(
6273
MMIO_CAPABILITY(Uart, uart) /* check default permissions */,
6374
{Permission::Global, Permission::Load, Permission::Store});
64-
check_permissions(
65-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, true, true, false),
66-
{Permission::Global,
67-
Permission::Load,
68-
Permission::Store,
69-
Permission::LoadStoreCapability});
70-
check_permissions(
71-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, true, false, true),
75+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
76+
Uart, uart, true, true, true, false, false),
77+
{Permission::Global,
78+
Permission::Load,
79+
Permission::Store,
80+
Permission::LoadStoreCapability});
81+
check_permissions(
82+
MMIO_CAPABILITY_WITH_PERMISSIONS(
83+
Uart, uart, true, true, false, true, false),
7284
{Permission::Global, Permission::Load, Permission::Store});
73-
check_permissions(
74-
MMIO_CAPABILITY_WITH_PERMISSIONS(Uart, uart, true, true, true, true),
75-
{Permission::Global,
76-
Permission::Load,
77-
Permission::Store,
78-
Permission::LoadStoreCapability,
79-
Permission::LoadMutable});
85+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
86+
Uart, uart, true, true, true, true, false),
87+
{Permission::Global,
88+
Permission::Load,
89+
Permission::Store,
90+
Permission::LoadStoreCapability,
91+
Permission::LoadMutable});
92+
check_permissions(MMIO_CAPABILITY_WITH_PERMISSIONS(
93+
Uart, uart, true, true, true, true, true),
94+
{Permission::Global,
95+
Permission::Load,
96+
Permission::Store,
97+
Permission::LoadStoreCapability,
98+
Permission::LoadMutable,
99+
Permission::LoadGlobal});
80100
return 0;
81101
}

0 commit comments

Comments
 (0)