Skip to content

Protection of spawned threads' TLS regions violates tracer expectations #663

@fw-immunant

Description

@fw-immunant

The native thread stack (not the IA2 per-compartment stacks) for child threads are allocated inside pthread_create, and are considered to be owned by whichever compartment calls pthread_create, as the new thread inherits the calling compartment. This unfortunately creates a conflict with the requirement (enforced by the tracer) that compartments cannot change the protection of memory owned by other compartments: each compartment sets up TLS by protecting its own TLS variables, changing their ownership from the thread-starting compartment to itself.

At program startup, the initial stack is not protected, so we don't see this problem, but if later in execution e.g. compartment 1 spawns a thread, then compartment 2's TLS variables will be part of the newly-allocated native stack and the tracer will see this as a compartment trying to steal memory.

We currently (as of #661) work around this by treating all stack allocations (mmap calls with the MAP_STACK flag) as owned by compartment 0 in the tracer:
track_memory_map.c:

    // XXX: glibc maps stacks for new threads inside pthread_create, and by default they would
    // inherit the compartment that starts them, but we need to partition out their TLS segments for
    // each compartment, which the tracer would reject as a compartment trying to steal another's
    // memory. for now, override the compartment to 0 for stacks so the later TLS protection
    // succeeds, but note that this is undermining compartment safety of the thread's initial
    // stack itself
    if (info->mmap.flags & MAP_STACK) {
      info->mmap.pkey = 0;
    }

But this is not secure, so we should find some other, watertight way to handle this case. We may need to do something like #283 where we validate that the TLS regions for other compartments have not been modified by the thread-spawning compartment after protecting them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions