allocator: correct token alloc error path
diff --git a/sdk/core/allocator/main.cc b/sdk/core/allocator/main.cc
index 8db5936..3b8e6cd 100644
--- a/sdk/core/allocator/main.cc
+++ b/sdk/core/allocator/main.cc
@@ -1175,16 +1175,24 @@
auto [sealed, obj] = allocate_sealed_unsealed(
timeout, heapCapability, key, sz, {Permission::Seal, Permission::Unseal});
{
+ /*
+ * Write the unsealed capability through the out parameter, while
+ * holding the allocator lock. That's a little heavy-handed, but it
+ * suffices to ensure that it won't be freed out from under us, so
+ * if it passes `check_pointer`, then the store won't trap.
+ */
LockGuard g{lock};
if (check_pointer<PermissionSet{
Permission::Store, Permission::LoadStoreCapability}>(unsealed))
{
*unsealed = obj;
- return sealed;
}
}
- heap_free(heapCapability, obj);
- return INVALID_SOBJ;
+ /*
+ * Regardless of whether we were able to store the unsealed pointer, return
+ * the sealed object.
+ */
+ return sealed;
}
__cheriot_minimum_stack(0x260) SObj token_sealed_alloc(Timeout *timeout,
diff --git a/sdk/include/thread_pool.h b/sdk/include/thread_pool.h
index bbf7fbd..c5e5d3c 100644
--- a/sdk/include/thread_pool.h
+++ b/sdk/include/thread_pool.h
@@ -158,9 +158,14 @@
detail::sealing_key_for_type<LambdaType>(),
sizeof(lambda),
&buffer);
- // Copy the lambda into the new allocation.
- // Note: We silence a warning here because we *do* want to
- // explicitly move, not forward.
+ /*
+ * Copy the lambda into the new allocation.
+ *
+ * If the above allocation has failed, this will trap.
+ *
+ * Note: We silence a warning here because we *do* want to
+ * explicitly move, not forward.
+ */
T *copy = new (buffer) T(
std::move(lambda)); // NOLINT(bugprone-move-forwarding-reference)
// Create the wrapper that will unseal and invoke the lambda.
diff --git a/sdk/include/token.h b/sdk/include/token.h
index 00111ec..76aec99 100644
--- a/sdk/include/token.h
+++ b/sdk/include/token.h
@@ -43,6 +43,9 @@
*
* An unsealed pointer to the newly allocated object is returned in
* `*unsealed`, the sealed pointer is returned as the return value.
+ * An invalid `unsealed` pointer does not constitute an error; the caller will
+ * still be given the sealed return value, assuming allocation was otherwise
+ * successful.
*
* The `key` parameter must have both the permit-seal and permit-unseal
* permissions.