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.