allocator: token_alloc tweaks
Document what we expect callers to do, and make our examples comply, but
also explicitly initialize the unsealed pointer for defense in depth.
diff --git a/examples/05.sealing/identifier.cc b/examples/05.sealing/identifier.cc
index c66db96..08b2c5d 100644
--- a/examples/05.sealing/identifier.cc
+++ b/examples/05.sealing/identifier.cc
@@ -36,7 +36,7 @@
// capabilities.
auto [unsealed, sealed] =
blocking_forever<token_allocate<Identifier>>(MALLOC_CAPABILITY, key());
- if (sealed == nullptr)
+ if (!sealed.is_valid())
{
return nullptr;
}
diff --git a/sdk/include/token.h b/sdk/include/token.h
index 76aec99..b1e2a09 100644
--- a/sdk/include/token.h
+++ b/sdk/include/token.h
@@ -190,14 +190,20 @@
/**
* Type-safe helper to allocate a sealed `T*`. Returns the sealed and unsealed
* pointers.
+ *
+ * Callers should check the sealed capability's tag to determine success.
*/
template<typename T>
__always_inline std::pair<T *, Sealed<T>>
token_allocate(Timeout *timeout, struct SObjStruct *heapCapability, SKey key)
{
- void *unsealed;
- SObj sealed = token_sealed_unsealed_alloc(
- timeout, heapCapability, key, sizeof(T), &unsealed);
+ /*
+ * Explicitly initialize unsealed, since callers like to check it, and not
+ * the sealed result, for validity.
+ */
+ void *unsealed = nullptr;
+ SObj sealed = token_sealed_unsealed_alloc(
+ timeout, heapCapability, key, sizeof(T), &unsealed);
return {static_cast<T *>(unsealed), Sealed<T>{sealed}};
}
diff --git a/sdk/lib/queue/queue_compartment.cc b/sdk/lib/queue/queue_compartment.cc
index 9aec00a..4ed5f52 100644
--- a/sdk/lib/queue/queue_compartment.cc
+++ b/sdk/lib/queue/queue_compartment.cc
@@ -186,7 +186,7 @@
}
auto [unsealed, sealed] = token_allocate<RestrictedEndpoint>(
timeout, heapCapability, receive_key());
- if (!unsealed)
+ if (!sealed.is_valid())
{
return -ENOMEM;
}
@@ -208,7 +208,7 @@
}
auto [unsealed, sealed] =
token_allocate<RestrictedEndpoint>(timeout, heapCapability, send_key());
- if (!unsealed)
+ if (!sealed.is_valid())
{
return -ENOMEM;
}