• Egor Pasko's avatar
    base/android: Split Loading and RELRO Sharing in ModernLinker · ee633e37
    Egor Pasko authored
    === API
    
    The current ModernLinker loading primitives look like:
        LoadLibraryCreateRelros(path, loadAddress, libInfo);
        LoadLibraryUseRelros(path, loadAddress, fd);
    
    This change replaces them with:
        LoadLibrary(path, loadAddress, libInfo, boolean spawnRelroRegion);
        UseRelros(libInfo);
    
    The UseRelros() can be called *while* the library code is running,
    atomically replacing the RELRO region with its version backed by shared
    memory, if all stars align.
    
    === Motivation
    
    The main motivation is to allow the App Zygote to provide the RELRO
    region on systems with App Zygote enabled, and use the usual mechanism
    when App Zygote is not available.
    
    === Implementation highlights
    
    With this change the ModernLinker still waits for mLibInfo to arrive
    from the browser process, as usual, but RELRO sharing already happens
    after the library is loaded. I believe, there is no code path to replace
    concurrently with execution.
    
    Semantically there are a few notable changes:
    
    1. When spawned, the RELRO FD is sealed as PROT_READ, making it
       impossible to make it writable ever again even by privileged
       processes. This way we should not worry where the code runs, in the
       Browser process or in the App Zygote.
    
    2. Library load ranges are explicitly including the range of
       PT_GNU_RELRO segment. It should not affect anything now, but can
       potentially eliminate hard to debug crashes in distant future.
    
    The main changes are in modern_linker_jni.cc where 'class NativeLibInfo'
    is introduced to hold basically the same information as the Java-side
    LibInfo, with the ability to perform the primitives described above, and
    import/export internally between Java-LibInfo and NativeLibInfo.
    
    Retrospectively the move into the class does *not* provide much useful
    encapsulation at the moment, but seems like a good direction if we later
    decide to use it for LegacyLinker, mock out parts for testing. The most
    part I dislike most is that the class behaves like two independent parts
    (LoadInfo and RelroInfo), some operations affect one, but not the other.
    I did not attempt to make the split, as things are still a bit coupled
    sometimes, maybe later.
    
    OK, this was long.
    
    Bug: 1154224
    Change-Id: I88af048a298310b56b3205a2b2dd765e2c69759a
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2560308Reviewed-by: default avatarBenoit L <lizeb@chromium.org>
    Commit-Queue: Egor Pasko <pasko@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#833245}
    ee633e37
linker_jni.h 7.24 KB