OSDN Git Service

Align-up and randomize shared libraries.
authorEvgenii Stepanov <eugenis@google.com>
Fri, 15 Jul 2016 23:31:42 +0000 (16:31 -0700)
committerEvgenii Stepanov <eugenis@google.com>
Wed, 20 Jul 2016 01:18:22 +0000 (18:18 -0700)
commitd13e9a603fa7e490853e6065240cdbfe532ada7a
tree638cb927828a152ff13531c5795f74c0edb356ab
parentd941f72e75c744a2493bbdbf759e96c32f764e68
Align-up and randomize shared libraries.

This change implements the following property:
  Any 2**N aligned memory region on size 2**N contains no more than one DSO.

The value N can be configured, with 16 or 18 looking like a good choice.
Additionally, DSOs are loaded at random page-aligned address inside these large
regions.

This change has dual purpose:
1. Larger values of N allow a lot more compact CFI shadow implementation.
   See change I14dfea630de468eb5620e7f55f92b1397ba06217.
   For example, CFI shadow for the system_server process has the following size (RSS, KB):
   152 for N = 12, 32 for N = 16, 16 for N = 18.
2. Extra randomization is good for security.

This change does not result in extra RAM usage, because everything is still page-aligned.
It does result in a bit more VM fragmentation because of the gaps between shared libraries.
As it turns out, this fragmentation is barely noticeable because the kernel creates new mapping
at the highest possible address, and we do enough small mappings to almost completely fill the
gaps (ex. in the Zygote the gaps are filled with .ttf file mappings and thread stacks).

I've measured VM fragmentation as the sum of all VM gaps (unmapped regions) that are larger
than 1MB according to /proc/$PID/maps. On aosp_angler-userdebug, the numbers are (in GB):

                |   N = 12  |  N = 18
system_server   |   521.9   |  521.1
zygote64        |   522.1   |  521.3
zygote32        |   2.55    |  2.55
mediaserver     |   4.00    |  4.00

Change-Id: Ia6df840dd409c82837efd1f263be420d9723c84a
libc/bionic/ndk_cruft.cpp
libc/private/bionic_macros.h
linker/linker.h
linker/linker_phdr.cpp