Secure-memory alignment overflow turns a huge allocation into a zero-byte block
Closed, WontfixPublic

Assigned To
Authored By
werner
Tue, Aug 4, 4:48 PM
Subscribers

Description

Secure-memory alignment overflow turns a huge allocation into a zero-byte block

The secure allocator rounds requests to 32 bytes by adding 31 without checking size_t overflow. Any nonzero request in the final 31 values of the type can wrap to zero; gcry_malloc_secure(SIZE_MAX) then returns a non-NULL secure pointer whose user address overlaps the next block's allocator metadata, so the caller's first ordinary write corrupts the secure pool.

Vulnerable code

src/secmem.c, _gcry_secmem_malloc_internal:

c
  /* Blocks are always a multiple of 32. */
  size = ((size + 31) / 32) * 32;

  mb = mb_get_new (pool, (memblock_t *) pool->mem, size);
  if (mb)
    {
      stats_update (pool, mb->size, 0);
      return &mb->aligned.c;
    }

Why it matters

This is reachable through the public gcry_malloc_secure(size_t) API. The audit harness confirmed that gcry_malloc_secure(SIZE_MAX) returned a non-NULL pointer for which gcry_is_secure was true; writing its first byte aliases pool bookkeeping. Corruption can crash later allocations/frees or create overlapping blocks holding keys. Exploitation requires an application to forward an extreme length and then trust the successful allocation, so this is not an automatic remote primitive in typical callers.

Capacity checks cannot help because they see the already rounded value zero. Secure calloc multiplication checks likewise do not protect the plain allocation API.

Proposed fix

Before alignment, reject size > SIZE_MAX - 31 with ENOMEM. Use a checked alignment helper, and reject a zero aligned result for any nonzero input before calling mb_get_new. Also prove the aligned size and header addition fit the allocator's internal type. Add public-API boundary tests for SIZE_MAX, SIZE_MAX - 30, SIZE_MAX - 31, and the largest representable aligned size, checking failure without pool mutation.

Related Objects

Event Timeline

werner created this task.
werner created this object with visibility "Public (No Login Required)".
werner created this object with edit policy "Contributor (Project)".
werner renamed this task from secure memory alignment overflow turns a huge allocation into a zero-byte block to Secure-memory alignment overflow turns a huge allocation into a zero-byte block.Tue, Aug 4, 5:13 PM

My internal comment was (redacted): Nobody with a sane mind will do a malloc(SIZE_T) but have a useful lower limit.

werner lowered the priority of this task from High to Low.Thu, Aug 6, 9:22 AM
werner added a project: Bug Report.
werner claimed this task.
werner shifted this object from the Restricted Space space to the S1 Public space.