Skip to content
  • Ben Gamari's avatar
    rts/linker: Ensure that code isn't writable · 120f2e53
    Ben Gamari authored and Marge Bot's avatar Marge Bot committed
    For many years the linker would simply map all of its memory with
    PROT_READ|PROT_WRITE|PROT_EXEC. However operating systems have been
    becoming increasingly reluctant to accept this practice (e.g. #17353
    and #12657) and for good reason: writable code is ripe for exploitation.
    
    Consequently mmapForLinker now maps its memory with
    PROT_READ|PROT_WRITE.  After the linker has finished filling/relocating
    the mapping it must then call mmapForLinkerMarkExecutable on the
    sections of the mapping which contain executable code.
    
    Moreover, to make all of this possible it was necessary to redesign the
    m32 allocator. First, we gave (in an earlier commit) each ObjectCode its
    own m32_allocator. This was necessary since code loading and symbol
    resolution/relocation are currently interleaved, meaning that it is not
    possible to enforce W^X when symbols from different objects reside in
    the same page.
    
    We then redesigned the m32 allocator to take advantage of the fact that
    all of the pages allocated with the allocator die at the same time
    (namely, when the owning ObjectCode is unloaded). This makes a number of
    things simpler (e.g. no more page reference counting; the interface
    provided by the allocator for freeing is simpler). See
    Note [M32 Allocator] for details.
    120f2e53