Secure-memory initialization leaves Linux capabilities active
Closed, WontfixPublic

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

Description

Secure-memory initialization leaves Linux capabilities active

In USE_CAPABILITIES builds, the only capability-clearing code is in the zero-size secure-memory branch. The documented, normal GCRYCTL_INIT_SECMEM call uses a nonzero pool size, locks the pool, and returns without dropping capabilities. A file- or ambient-capability process whose real and effective UIDs are equal therefore retains all effective and permitted kernel authority.

Vulnerable code

src/secmem.c, _gcry_secmem_init_internal:

c
  if (!n)
    {
#ifdef USE_CAPABILITIES
      /* drop all capabilities */
      if (!no_priv_drop)
        {
          cap_t cap;

          cap = cap_from_text ("all-eip");
          cap_set_proc (cap);
          cap_free (cap);
        }

The ordinary path never reaches that block:

c
  else
    {
      if (n < MINIMUM_POOL_SIZE)
	n = MINIMUM_POOL_SIZE;
      if (! pool->okay)
	{
	  init_pool (pool, n);
	  lock_pool_pages (pool->mem, n);
	}

Why it matters

lock_pool_pages only performs a UID drop for the classic uid != 0 && geteuid() == 0 case. It does nothing to capability sets when real and effective UIDs match. Code running after initialization thus keeps not only CAP_IPC_LOCK, but any unrelated capabilities granted to the process, increasing the impact of a later memory-safety or command-execution flaw. The issue requires the optional --with-capabilities build and a capability-bearing application; it does not grant privileges to an otherwise unprivileged process.

Proposed fix

After the pool is locked on the nonzero path, clear effective, permitted, and inheritable capability sets unless GCRYCTL_DISABLE_PRIV_DROP was explicitly used. Check cap_from_text, cap_set_proc, and post-drop state, and fail initialization if dropping fails. Add a Linux namespace integration test that starts with a harmless capability, performs nonzero secure-memory initialization, and verifies empty CapEff, CapPrm, and CapInh sets afterward.

Related Objects

StatusAssignedTask
Wontfix• werner

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 initialization leaves linux capabilities active to Secure-memory initialization leaves Linux capabilities active.Tue, Aug 4, 5:14 PM

My internal comment was: The proposed fix would be a semantic change. In reality we don't do any privilege dropping because running gpg or other programs as suid is out of fashion and need for 20 years.

• werner lowered the priority of this task from High to Normal.Thu, Aug 6, 9:20 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.