18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)package org.chromium.content.app; 68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)import android.os.Bundle; 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)import android.os.Parcel; 98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)import android.os.ParcelFileDescriptor; 10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import android.os.Parcelable; 118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)import android.util.Log; 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import org.chromium.base.SysUtils; 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import java.io.File; 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import java.io.FileInputStream; 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import java.util.HashMap; 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import java.util.Map; 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)/* 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Technical note: 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * The point of this class is to provide an alternative to System.loadLibrary() 248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * to load native shared libraries. One specific feature that it supports is the 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * ability to save RAM by sharing the ELF RELRO sections between renderer 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * processes. 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * When two processes load the same native library at the _same_ memory address, 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * the content of their RELRO section (which includes C++ vtables or any 308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * constants that contain pointers) will be largely identical [1]. 318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * By default, the RELRO section is backed by private RAM in each process, 338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * which is still significant on mobile (e.g. 1.28 MB / process on Chrome 30 for 348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Android). 358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * However, it is possible to save RAM by creating a shared memory region, 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * copy the RELRO content into it, then have each process swap its private, 388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * regular RELRO, with a shared, read-only, mapping of the shared one. 398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * This trick saves 98% of the RELRO section size per extra process, after the 418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * first one. On the other hand, this requires careful communication between 428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * the process where the shared RELRO is created and the one(s) where it is used. 438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Note that swapping the regular RELRO with the shared one is not an atomic 458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * operation. Care must be taken that no other thread tries to run native code 468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * that accesses it during it. In practice, this means the swap must happen 478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * before library native code is executed. 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * [1] The exceptions are pointers to external, randomized, symbols, like 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * those from some system libraries, but these are very few in practice. 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)/* 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Security considerations: 558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Whether the browser process loads its native libraries at the same 578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * addresses as the service ones (to save RAM by sharing the RELRO too) 588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * depends on the configuration variable BROWSER_SHARED_RELRO_CONFIG below. 598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Not using fixed library addresses in the browser process is preferred 618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * for regular devices since it maintains the efficacy of ASLR as an 628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * exploit mitigation across the render <-> browser privilege boundary. 638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - The shared RELRO memory region is always forced read-only after creation, 658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * which means it is impossible for a compromised service process to map 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * it read-write (e.g. by calling mmap() or mprotect()) and modify its 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * content, altering values seen in other service processes. 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Unfortunately, certain Android systems use an old, buggy kernel, that 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * doesn't check Ashmem region permissions correctly. See CVE-2011-1149 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * for details. This linker probes the system on startup and will completely 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * disable shared RELROs if it detects the problem. For the record, this is 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * common for Android emulator system images (which are still based on 2.6.29) 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Once the RELRO ashmem region is mapped into a service process' address 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * space, the corresponding file descriptor is immediately closed. The 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * file descriptor is kept opened in the browser process, because a copy needs 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * to be sent to each new potential service process. 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - The common library load addresses are randomized for each instance of 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * the program on the device. See computeRandomBaseLoadAddress() for more 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * details on how this is computed. 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - When loading several libraries in service processes, a simple incremental 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * approach from the original random base load address is used. This is 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * sufficient to deal correctly with component builds (which can use dozens 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * of shared libraries), while regular builds always embed a single shared 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * library per APK. 898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/** 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Here's an explanation of how this class is supposed to be used: 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Native shared libraries should be loaded with Linker.loadLibrary(), 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * instead of System.loadLibrary(). The two functions take the same parameter 968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * and should behave the same (at a high level). 978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Before loading any library, prepareLibraryLoad() should be called. 998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - After loading all libraries, finishLibraryLoad() should be called, before 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * running any native code from any of the libraries (except their static 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * constructors, which can't be avoided). 1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - A service process shall call either initServiceProcess() or 1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * disableSharedRelros() early (i.e. before any loadLibrary() call). 1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Otherwise, the linker considers that it is running inside the browser 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * process. This is because various content-based projects have vastly 1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * different initialization paths. 1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * disableSharedRelros() completely disables shared RELROs, and loadLibrary() 1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * will behave exactly like System.loadLibrary(). 1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * initServiceProcess(baseLoadAddress) indicates that shared RELROs are to be 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * used in this process. 1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - The browser is in charge of deciding where in memory each library should 1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * be loaded. This address must be passed to each service process (see 1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * LinkerParams.java for a helper class to do so). 1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - The browser will also generate shared RELROs for each library it loads. 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * More specifically, by default when in the browser process, the linker 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * will: 1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Load libraries randomly (just like System.loadLibrary()). 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Compute the fixed address to be used to load the same library 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * in service processes. 1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Create a shared memory region populated with the RELRO region 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * content pre-relocated for the specific fixed address above. 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Note that these shared RELRO regions cannot be used inside the browser 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * process. They are also never mapped into it. 1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * This behaviour is altered by the BROWSER_SHARED_RELRO_CONFIG configuration 1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * variable below, which may force the browser to load the libraries at 1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * fixed addresses to. 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - Once all libraries are loaded in the browser process, one can call 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * getSharedRelros() which returns a Bundle instance containing a map that 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * links each loaded library to its shared RELRO region. 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * This Bundle must be passed to each service process, for example through 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * a Binder call (note that the Bundle includes file descriptors and cannot 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * be added as an Intent extra). 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * - In a service process, finishLibraryLoad() will block until the RELRO 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * section Bundle is received. This is typically done by calling 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * useSharedRelros() from another thread. 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * This method also ensures the process uses the shared RELROs. 1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)public class Linker { 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Log tag for this class. This must match the name of the linker's native library. 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static final String TAG = "content_android_linker"; 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Set to true to enable debug logs. 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static final boolean DEBUG = false; 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Constants used to control the behaviour of the browser process with 1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // regards to the shared RELRO section. 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // NEVER -> The browser never uses it itself. 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // LOW_RAM_ONLY -> It is only used on devices with low RAM. 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // ALWAYS -> It is always used. 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // NOTE: These names are known and expected by the Linker test scripts. 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final int BROWSER_SHARED_RELRO_CONFIG_NEVER = 0; 1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final int BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY = 1; 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final int BROWSER_SHARED_RELRO_CONFIG_ALWAYS = 2; 1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Configuration variable used to control how the browser process uses the 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // shared RELRO. Only change this while debugging linker-related issues. 1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // NOTE: This variable's name is known and expected by the Linker test scripts. 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final int BROWSER_SHARED_RELRO_CONFIG = 1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BROWSER_SHARED_RELRO_CONFIG_ALWAYS; 1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Constants used to control the value of sMemoryDeviceConfig. 1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // INIT -> Value is undetermined (will check at runtime). 1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // LOW -> This is a low-memory device. 1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // NORMAL -> This is not a low-memory device. 1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final int MEMORY_DEVICE_CONFIG_INIT = 0; 1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final int MEMORY_DEVICE_CONFIG_LOW = 1; 1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final int MEMORY_DEVICE_CONFIG_NORMAL = 2; 1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Indicates if this is a low-memory device or not. The default is to 1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // determine this by probing the system at runtime, but this can be forced 1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // for testing by calling setMemoryDeviceConfig(). 1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static int sMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_INIT; 1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Becomes true after linker initialization. 1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static boolean sInitialized = false; 1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Set to true to indicate that the system supports safe sharing of RELRO sections. 1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static boolean sRelroSharingSupported = false; 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Set to true if this runs in the browser process. Disabled by initServiceProcess(). 1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static boolean sInBrowserProcess = true; 1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Becomes true to indicate this process needs to wait for a shared RELRO in 1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // finishLibraryLoad(). 1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static boolean sWaitForSharedRelros = false; 2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Becomes true when initialization determines that the browser process can use the 2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // shared RELRO. 2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static boolean sBrowserUsesSharedRelro = false; 2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The map of all RELRO sections either created or used in this process. 2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static Bundle sSharedRelros = null; 2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Current common random base load address. 2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static long sBaseLoadAddress = 0; 2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Current fixed-location load address for the next library called by loadLibrary(). 2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static long sCurrentLoadAddress = 0; 2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Becomes true if any library fails to load at a given, non-0, fixed address. 2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static boolean sLoadAtFixedAddressFailed = false; 2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Becomes true once prepareLibraryLoad() has been called. 2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static boolean sPrepareLibraryLoadCalled = false; 2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Used internally to initialize the linker's static data. Assume lock is held. 2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static void ensureInitializedLocked() { 2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert Thread.holdsLock(Linker.class); 2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!sInitialized) { 2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sRelroSharingSupported = false; 2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (NativeLibraries.USE_LINKER) { 2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Loading lib" + TAG + ".so"); 2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try { 2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) System.loadLibrary(TAG); 2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } catch (UnsatisfiedLinkError e) { 2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // In a component build, the ".cr" suffix is added to each library name. 2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) System.loadLibrary(TAG + ".cr"); 2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sRelroSharingSupported = nativeCanUseSharedRelro(); 2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!sRelroSharingSupported) 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.w(TAG, "This system cannot safely share RELRO sections"); 2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) else { 2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "This system supports safe shared RELRO sections"); 2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sMemoryDeviceConfig == MEMORY_DEVICE_CONFIG_INIT) { 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sMemoryDeviceConfig = SysUtils.isLowEndDevice() ? 2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MEMORY_DEVICE_CONFIG_LOW : MEMORY_DEVICE_CONFIG_NORMAL; 2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) switch (BROWSER_SHARED_RELRO_CONFIG) { 2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case BROWSER_SHARED_RELRO_CONFIG_NEVER: 2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBrowserUsesSharedRelro = false; 2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY: 2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBrowserUsesSharedRelro = 2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) (sMemoryDeviceConfig == MEMORY_DEVICE_CONFIG_LOW); 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sBrowserUsesSharedRelro) 2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.w(TAG, "Low-memory device: shared RELROs used in all processes"); 2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case BROWSER_SHARED_RELRO_CONFIG_ALWAYS: 2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.w(TAG, "Beware: shared RELROs used in all processes!"); 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBrowserUsesSharedRelro = true; 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) default: 2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert false : "Unreached"; 2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Linker disabled"); 2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!sRelroSharingSupported) { 2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Sanity. 2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBrowserUsesSharedRelro = false; 2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sWaitForSharedRelros = false; 2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sInitialized = true; 2758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * A public interface used to run runtime linker tests after loading 2808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * libraries. Should only be used to implement the linker unit tests, 2818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * which is controlled by the value of NativeLibraries.ENABLE_LINKER_TESTS 2828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * configured at build time. 2838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 2848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public interface TestRunner { 2858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 2868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Run runtime checks and return true if they all pass. 2878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param memoryDeviceConfig The current memory device configuration. 2888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param inBrowserProcess true iff this is the browser process. 2898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 2908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public boolean runChecks(int memoryDeviceConfig, boolean inBrowserProcess); 2918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The name of a class that implements TestRunner. 2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static String sTestRunnerClassName = null; 2958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 2978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Set the TestRunner by its class name. It will be instantiated at 2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * runtime after all libraries are loaded. 2998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param testRunnerClassName null or a String for the class name of the 3008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * TestRunner to use. 3018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static void setTestRunnerClassName(String testRunnerClassName) { 3038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "setTestRunnerByClassName(" + testRunnerClassName + ") called"); 3048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!NativeLibraries.ENABLE_LINKER_TESTS) { 3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Ignore this in production code to prevent malvolent runtime injection. 3078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 3118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert sTestRunnerClassName == null; 3128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sTestRunnerClassName = testRunnerClassName; 3138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 3178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this to retrieve the name of the current TestRunner class name 3188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * if any. This can be useful to pass it from the browser process to 3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * child ones. 3208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return null or a String holding the name of the class implementing 3218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * the TestRunner set by calling setTestRunnerClassName() previously. 3228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 3238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static String getTestRunnerClassName() { 3248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 3258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return sTestRunnerClassName; 3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this method before any other Linker method to force a specific 3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * memory device configuration. Should only be used for testing. 332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * @param memoryDeviceConfig either MEMORY_DEVICE_CONFIG_LOW or MEMORY_DEVICE_CONFIG_NORMAL. 3338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 3348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static void setMemoryDeviceConfig(int memoryDeviceConfig) { 3358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "setMemoryDeviceConfig(" + memoryDeviceConfig + ") called"); 3368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Sanity check. This method should only be called during tests. 3378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert NativeLibraries.ENABLE_LINKER_TESTS; 3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 3398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert sMemoryDeviceConfig == MEMORY_DEVICE_CONFIG_INIT; 3408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert memoryDeviceConfig == MEMORY_DEVICE_CONFIG_LOW || 3418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) memoryDeviceConfig == MEMORY_DEVICE_CONFIG_NORMAL; 3428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) { 3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (memoryDeviceConfig == MEMORY_DEVICE_CONFIG_LOW) 3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, "Simulating a low-memory device"); 3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) else 3468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, "Simulating a regular-memory device"); 3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sMemoryDeviceConfig = memoryDeviceConfig; 3498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this method to determine if this content-based project must 3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * use this linker. If not, System.loadLibrary() should be used to load 3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * libraries instead. 3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static boolean isUsed() { 3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Only GYP targets that are APKs and have the 'use_content_linker' variable 3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // defined as 1 will use this linker. For all others (the default), the 3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // auto-generated NativeLibraries.USE_LINKER variable will be false. 3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!NativeLibraries.USE_LINKER) 3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ensureInitializedLocked(); 3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // At the moment, there is also no point in using this linker if the 3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // system does not support RELRO sharing safely. 3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return sRelroSharingSupported; 3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this method just before loading any native shared libraries in this process. 3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static void prepareLibraryLoad() { 3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "prepareLibraryLoad() called"); 3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 3788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sPrepareLibraryLoadCalled = true; 3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sInBrowserProcess) { 3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Force generation of random base load address, as well 3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // as creation of shared RELRO sections in this process. 3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) setupBaseLoadAddressLocked(); 3848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this method just after loading all native shared libraries in this process. 3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Note that when in a service process, this will block until the RELRO bundle is 3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * received, i.e. when another thread calls useSharedRelros(). 3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public static void finishLibraryLoad() { 3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "finishLibraryLoad() called"); 3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, String.format( 3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "sInBrowserProcess=%s sBrowserUsesSharedRelro=%s sWaitForSharedRelros=%s", 3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sInBrowserProcess ? "true" : "false", 3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBrowserUsesSharedRelro ? "true" : "false", 4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sWaitForSharedRelros ? "true" : "false")); 4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sLoadedLibraries == null) { 4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "No libraries loaded"); 4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 4058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sInBrowserProcess) { 4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Create new Bundle containing RELRO section information 4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // for all loaded libraries. Make it available to getSharedRelros(). 4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sSharedRelros = createBundleFromLibInfoMap(sLoadedLibraries); 4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) { 4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, "Shared RELRO created"); 4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) dumpBundle(sSharedRelros); 4128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sBrowserUsesSharedRelro) { 4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) useSharedRelrosLocked(sSharedRelros); 4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sWaitForSharedRelros) { 4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert !sInBrowserProcess; 4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Wait until the shared relro bundle is received from useSharedRelros(). 4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) while (sSharedRelros == null) { 4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try { 4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Linker.class.wait(); 4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } catch (InterruptedException ie) { 4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) useSharedRelrosLocked(sSharedRelros); 4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Clear the Bundle to ensure its file descriptor references can't be reused. 4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sSharedRelros.clear(); 4328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sSharedRelros = null; 4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (NativeLibraries.ENABLE_LINKER_TESTS && sTestRunnerClassName != null) { 4378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The TestRunner implementation must be instantiated _after_ 4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // all libraries are loaded to ensure that its native methods 4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // are properly registered. 4408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Instantiating " + sTestRunnerClassName); 4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TestRunner testRunner = null; 4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try { 4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) testRunner = (TestRunner) 4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Class.forName(sTestRunnerClassName).newInstance(); 4458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } catch (Exception e) { 4468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.e(TAG, "Could not extract test runner class name", e); 4478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) testRunner = null; 4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (testRunner != null) { 4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!testRunner.runChecks(sMemoryDeviceConfig, sInBrowserProcess)) { 4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.wtf(TAG, "Linker runtime tests failed in this process!!"); 4528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert false; 4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, "All linker tests passed!"); 4558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "finishLibraryLoad() exiting"); 460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 4618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 4638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this to send a Bundle containing the shared RELRO sections to be 4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * used in this process. If initServiceProcess() was previously called, 4658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * finishLibraryLoad() will not exit until this method is called in another 4668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * thread with a non-null value. 4678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param bundle The Bundle instance containing a map of shared RELRO sections 4688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * to use in this process. 4698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 4708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static void useSharedRelros(Bundle bundle) { 4718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Ensure the bundle uses the application's class loader, not the framework 4728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // one which doesn't know anything about LibInfo. 4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (bundle != null) 4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bundle.setClassLoader(LibInfo.class.getClassLoader()); 4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "useSharedRelros() called with " + bundle); 4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Note that in certain cases, this can be called before 4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // initServiceProcess() in service processes. 4818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sSharedRelros = bundle; 4828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Tell any listener blocked in finishLibraryLoad() about it. 4838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Linker.class.notifyAll(); 4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this to retrieve the shared RELRO sections created in this process, 4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * after loading all libraries. 4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return a new Bundle instance, or null if RELRO sharing is disabled on 4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * this system, or if initServiceProcess() was called previously. 4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static Bundle getSharedRelros() { 4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "getSharedRelros() called"); 4958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 4968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!sInBrowserProcess) { 4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "... returning null Bundle"); 4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return null; 4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Return the Bundle created in finishLibraryLoad(). 5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "... returning " + sSharedRelros); 5038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return sSharedRelros; 5048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 5098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this method before loading any libraries to indicate that this 5108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * process shall neither create or reuse shared RELRO sections. 5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 5128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static void disableSharedRelros() { 5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "disableSharedRelros() called"); 5148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 5158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sInBrowserProcess = false; 5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sWaitForSharedRelros = false; 5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBrowserUsesSharedRelro = false; 5188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this method before loading any libraries to indicate that this 5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * process is ready to reuse shared RELRO sections from another one. 5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Typically used when starting service processes. 5258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param baseLoadAddress the base library load address to use. 5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static void initServiceProcess(long baseLoadAddress) { 5288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, String.format("initServiceProcess(0x%x) called", baseLoadAddress)); 5298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ensureInitializedLocked(); 5318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sInBrowserProcess = false; 5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBrowserUsesSharedRelro = false; 5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sRelroSharingSupported) { 5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sWaitForSharedRelros = true; 5358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBaseLoadAddress = baseLoadAddress; 5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sCurrentLoadAddress = baseLoadAddress; 5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 5428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Retrieve the base load address of all shared RELRO sections. 5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * This also enforces the creation of shared RELRO sections in 5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * prepareLibraryLoad(), which can later be retrieved with getSharedRelros(). 5458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return a common, random base load address, or 0 if RELRO sharing is 5468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * disabled. 5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static long getBaseLoadAddress() { 5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 5508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ensureInitializedLocked(); 5518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!sInBrowserProcess) { 5528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.w(TAG, "Shared RELRO sections are disabled in this process!"); 5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return 0; 5548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) setupBaseLoadAddressLocked(); 5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, String.format("getBaseLoadAddress() returns 0x%x", 5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBaseLoadAddress)); 5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return sBaseLoadAddress; 5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Used internally to lazily setup the common random base load address. 5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static void setupBaseLoadAddressLocked() { 5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert Thread.holdsLock(Linker.class); 5668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sBaseLoadAddress == 0) { 5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) long address = computeRandomBaseLoadAddress(); 5688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sBaseLoadAddress = address; 5698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sCurrentLoadAddress = address; 5708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (address == 0) { 571a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If the computed address is 0, there are issues with the 572a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // entropy source, so disable RELRO shared / fixed load addresses. 573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Log.w(TAG, "Disabling shared RELROs due to bad entropy sources"); 574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sBrowserUsesSharedRelro = false; 575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sWaitForSharedRelros = false; 5768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 5828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Compute a random base load address where to place loaded libraries. 5838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return new base load address, or 0 if the system does not support 5848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * RELRO sharing. 5858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 5868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static long computeRandomBaseLoadAddress() { 5878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The kernel ASLR feature will place randomized mappings starting 5888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // from this address. Never try to load anything above this 5898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // explicitly to avoid random conflicts. 5908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) final long baseAddressLimit = 0x40000000; 5918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Start loading libraries from this base address. 5938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) final long baseAddress = 0x20000000; 5948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Maximum randomized base address value. Used to ensure a margin 5968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // of 192 MB below baseAddressLimit. 5978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) final long baseAddressMax = baseAddressLimit - 192 * 1024 * 1024; 5988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The maximum limit of the desired random offset. 6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) final long pageSize = nativeGetPageSize(); 601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) final int offsetLimit = (int) ((baseAddressMax - baseAddress) / pageSize); 6028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Get the greatest power of 2 that is smaller or equal to offsetLimit. 6048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int numBits = 30; 6058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (; numBits > 1; numBits--) { 6068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if ((1 << numBits) <= offsetLimit) 6078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) break; 6088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) { 6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) final int maxValue = (1 << numBits) - 1; 6128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, String.format("offsetLimit=%d numBits=%d maxValue=%d (0x%x)", 6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) offsetLimit, numBits, maxValue, maxValue)); 6148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Find a random offset between 0 and (2^numBits - 1), included. 6178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int offset = getRandomBits(numBits); 6188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) long address = 0; 6198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (offset >= 0) 6208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) address = baseAddress + offset * pageSize; 6218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) { 6238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, 6248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) String.format("Linker.computeRandomBaseLoadAddress() return 0x%x", 6258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) address)); 6268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return address; 6288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 6318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Return a cryptographically-strong random number of numBits bits. 6328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param numBits The number of bits in the result. Must be in 1..31 range. 6338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return A random integer between 0 and (2^numBits - 1), inclusive, or -1 6348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * in case of error (e.g. if /dev/urandom can't be opened or read). 6358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 6368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static int getRandomBits(int numBits) { 6378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Sanity check. 6388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert numBits > 0; 6398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert numBits < 32; 6408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FileInputStream input; 6428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try { 6438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // A naive implementation would read a 32-bit integer then use modulo, but 6448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // this introduces a slight bias. Instead, read 32-bit integers from the 6458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // entropy source until the value is positive but smaller than maxLimit. 6468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) input = new FileInputStream(new File("/dev/urandom")); 6478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } catch (Exception e) { 6488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.e(TAG, "Could not open /dev/urandom", e); 6498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 6508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int result = 0; 6538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try { 654a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (int n = 0; n < 4; n++) { 6558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) result = (result << 8) | (input.read() & 255); 656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 6578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } catch (Exception e) { 6588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.e(TAG, "Could not read /dev/urandom", e); 6598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return -1; 6608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } finally { 6618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try { 6628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) input.close(); 6638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } catch (Exception e) { 6648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Can't really do anything here. 6658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) result &= (1 << numBits) - 1; 6688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) { 6708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, String.format( 6718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "getRandomBits(%d) returned %d", numBits, result)); 6728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return result; 6758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Used for debugging only. 6788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static void dumpBundle(Bundle bundle) { 6798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Bundle has " + bundle.size() + " items: " + bundle); 6808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 6838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Use the shared RELRO section from a Bundle received form another process. 6848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Call this after calling setBaseLoadAddress() then loading all libraries 6858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * with loadLibrary(). 686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * @param bundle Bundle instance generated with createSharedRelroBundle() in 6878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * another process. 6888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 6898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static void useSharedRelrosLocked(Bundle bundle) { 6908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert Thread.holdsLock(Linker.class); 6918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Linker.useSharedRelrosLocked() called"); 6938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (bundle == null) { 6958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "null bundle!"); 6968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 6978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 6988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 6998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!sRelroSharingSupported) { 7008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "System does not support RELRO sharing"); 7018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 7028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sLoadedLibraries == null) { 7058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "No libraries loaded!"); 7068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 7078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) dumpBundle(bundle); 7108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) HashMap<String, LibInfo> relroMap = createLibInfoMapFromBundle(bundle); 7118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Apply the RELRO section to all libraries that were already loaded. 7138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (Map.Entry<String, LibInfo> entry : relroMap.entrySet()) { 7148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) String libName = entry.getKey(); 7158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LibInfo libInfo = entry.getValue(); 7168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!nativeUseSharedRelro(libName, libInfo)) { 7178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.w(TAG, "Could not use shared RELRO section for " + libName); 7188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 7198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Using shared RELRO section for " + libName); 7208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // In service processes, close all file descriptors from the map now. 7248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!sInBrowserProcess) 7258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) closeLibInfoMap(relroMap); 7268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Linker.useSharedRelrosLocked() exiting"); 7288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 7318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Returns whether the linker was unable to load one library at a given fixed address. 7328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 7338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return true if at least one library was not loaded at the expected fixed address. 7348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 7358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static boolean loadAtFixedAddressFailed() { 7368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return sLoadAtFixedAddressFailed; 7378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 7408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Load a native shared library with the Chromium linker. 7418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * If neither initSharedRelro() or readFromBundle() were called 7428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * previously, this uses the standard linker (i.e. System.loadLibrary()). 7438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * 7448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param library The library's base name. 7458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 7468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static void loadLibrary(String library) { 7478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "loadLibrary: " + library); 7488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Don't self-load the linker. This is because the build system is 7508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // not clever enough to understand that all the libraries packaged 7518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // in the final .apk don't need to be explicitly loaded. 7528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Also deal with the component build that adds a .cr suffix to the name. 7538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (library.equals(TAG) || library.equals(TAG + ".cr")) { 7548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "ignoring self-linker load"); 7558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 7568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) synchronized (Linker.class) { 7598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ensureInitializedLocked(); 7608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Security: Ensure prepareLibraryLoad() was called before. 7628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // In theory, this can be done lazily here, but it's more consistent 7638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // to use a pair of functions (i.e. prepareLibraryLoad() + finishLibraryLoad()) 7648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // that wrap all calls to loadLibrary() in the library loader. 7658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) assert sPrepareLibraryLoadCalled; 7668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) String libName = System.mapLibraryName(library); 7688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sLoadedLibraries == null) 7708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sLoadedLibraries = new HashMap<String, LibInfo>(); 7718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sLoadedLibraries.containsKey(libName)) { 7738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Not loading " + libName + " twice"); 7748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 7758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LibInfo libInfo = new LibInfo(); 7788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) long loadAddress = 0; 7798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if ((sInBrowserProcess && sBrowserUsesSharedRelro) || sWaitForSharedRelros) { 7808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Load the library at a fixed address. 7818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) loadAddress = sCurrentLoadAddress; 7828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!nativeLoadLibrary(libName, loadAddress, libInfo)) { 7858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) String errorMessage = "Unable to load library: " + libName; 7868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.e(TAG, errorMessage); 7878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) throw new UnsatisfiedLinkError(errorMessage); 7888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Keep track whether the library has been loaded at the expected load address. 7908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (loadAddress != 0 && loadAddress != libInfo.mLoadAddress) 7918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sLoadAtFixedAddressFailed = true; 7928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Print the load address to the logcat when testing the linker. The format 7948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // of the string is expected by the Python test_runner script as one of: 7958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // BROWSER_LIBRARY_ADDRESS: <library-name> <address> 7968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // RENDERER_LIBRARY_ADDRESS: <library-name> <address> 7978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Where <library-name> is the library name, and <address> is the hexadecimal load 7988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // address. 7998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (NativeLibraries.ENABLE_LINKER_TESTS) { 8008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.i(TAG, String.format( 8018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "%s_LIBRARY_ADDRESS: %s %x", 8028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sInBrowserProcess ? "BROWSER" : "RENDERER", 8038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) libName, 8048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) libInfo.mLoadAddress)); 8058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sInBrowserProcess) { 8088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Create a new shared RELRO section at the 'current' fixed load address. 8098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!nativeCreateSharedRelro(libName, sCurrentLoadAddress, libInfo)) { 810a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Log.w(TAG, String.format("Could not create shared RELRO for %s at %x", 811a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) libName, sCurrentLoadAddress)); 8128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 8138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, 8148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) String.format( 8158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "Created shared RELRO for %s at %x: %s", 8168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) libName, 8178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sCurrentLoadAddress, 8188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) libInfo.toString())); 8198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sCurrentLoadAddress != 0) { 8238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Compute the next current load address. If sBaseLoadAddress 8248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // is not 0, this is an explicit library load address. Otherwise, 8258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // this is an explicit load address for relocated RELRO sections 8268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // only. 8278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sCurrentLoadAddress = libInfo.mLoadAddress + libInfo.mLoadSize; 8288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sLoadedLibraries.put(libName, libInfo); 8318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (DEBUG) Log.i(TAG, "Library details " + libInfo.toString()); 8328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 8348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 8368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Native method used to load a library. 8378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param library Platform specific library name (e.g. libfoo.so) 8388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param loadAddress Explicit load address, or 0 for randomized one. 839a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * @param libInfo If not null, the mLoadAddress and mLoadSize fields 8408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * of this LibInfo instance will set on success. 8418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return true for success, false otherwise. 8428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 8438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static native boolean nativeLoadLibrary(String library, 844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) long loadAddress, 8458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LibInfo libInfo); 8468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 8488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Native method used to create a shared RELRO section. 8498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * If the library was already loaded at the same address using 8508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * nativeLoadLibrary(), this creates the RELRO for it. Otherwise, 8518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * this loads a new temporary library at the specified address, 8528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * creates and extracts the RELRO section from it, then unloads it. 8538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param library Library name. 8548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param loadAddress load address, which can be different from the one 8558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * used to load the library in the current process! 856a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * @param libInfo libInfo instance. On success, the mRelroStart, mRelroSize 8578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * and mRelroFd will be set. 8588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return true on success, false otherwise. 8598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 8608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static native boolean nativeCreateSharedRelro(String library, 8618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) long loadAddress, 8628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LibInfo libInfo); 8638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 8658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Native method used to use a shared RELRO section. 8668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param library Library name. 8678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @param libInfo A LibInfo instance containing valid RELRO information 8688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * @return true on success. 8698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 8708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static native boolean nativeUseSharedRelro(String library, 8718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LibInfo libInfo); 8728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 8748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Checks that the system supports shared RELROs. Old Android kernels 8758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * have a bug in the way they check Ashmem region protection flags, which 8768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * makes using shared RELROs unsafe. This method performs a simple runtime 8778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * check for this misfeature, even though nativeEnableSharedRelro() will 8788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * always fail if this returns false. 8798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 8808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static native boolean nativeCanUseSharedRelro(); 8818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Returns the native page size in bytes. 8838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static native long nativeGetPageSize(); 8848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) /** 8868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Record information for a given library. 8878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * IMPORTANT: Native code knows about this class's fields, so 8888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * don't change them without modifying the corresponding C++ sources. 8898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) * Also, the LibInfo instance owns the ashmem file descriptor. 8908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) */ 8918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static class LibInfo implements Parcelable { 8928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public LibInfo() { 8948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mLoadAddress = 0; 8958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mLoadSize = 0; 8968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroStart = 0; 8978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroSize = 0; 8988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroFd = -1; 8998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public void close() { 9028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (mRelroFd >= 0) { 903a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) try { 904a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ParcelFileDescriptor.adoptFd(mRelroFd).close(); 905a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } catch (java.io.IOException e) { 906a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 907a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mRelroFd = -1; 9088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // from Parcelable 9128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public LibInfo(Parcel in) { 9138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mLoadAddress = in.readLong(); 9148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mLoadSize = in.readLong(); 9158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroStart = in.readLong(); 9168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroSize = in.readLong(); 9178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ParcelFileDescriptor fd = in.readFileDescriptor(); 9188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroFd = fd.detachFd(); 9198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // from Parcelable 9228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) @Override 9238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public void writeToParcel(Parcel out, int flags) { 9248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (mRelroFd >= 0) { 9258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) out.writeLong(mLoadAddress); 9268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) out.writeLong(mLoadSize); 9278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) out.writeLong(mRelroStart); 9288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) out.writeLong(mRelroSize); 9298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) try { 9308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ParcelFileDescriptor fd = ParcelFileDescriptor.fromFd(mRelroFd); 9318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) fd.writeToParcel(out, 0); 9328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) fd.close(); 9338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } catch (java.io.IOException e) { 9348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Log.e(TAG, "Cant' write LibInfo file descriptor to parcel", e); 9358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // from Parcelable 9408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) @Override 9418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public int describeContents() { 9428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return Parcelable.CONTENTS_FILE_DESCRIPTOR; 9438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // from Parcelable 946a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public static final Parcelable.Creator<LibInfo> CREATOR = 947a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new Parcelable.Creator<LibInfo>() { 948a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) @Override 949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public LibInfo createFromParcel(Parcel in) { 950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return new LibInfo(in); 951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 9528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 953a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) @Override 954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public LibInfo[] newArray(int size) { 955a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return new LibInfo[size]; 956a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 957a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) }; 9588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 959a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) @Override 9608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public String toString() { 9618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return String.format("[load=0x%x-0x%x relro=0x%x-0x%x fd=%d]", 9628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mLoadAddress, 9638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mLoadAddress + mLoadSize, 9648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroStart, 9658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroStart + mRelroSize, 9668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mRelroFd); 9678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // IMPORTANT: Don't change these fields without modifying the 9708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // native code that accesses them directly! 9718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public long mLoadAddress; // page-aligned library load address. 9728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public long mLoadSize; // page-aligned library load size. 9738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public long mRelroStart; // page-aligned address in memory, or 0 if none. 9748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public long mRelroSize; // page-aligned size in memory, or 0. 9758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public int mRelroFd; // ashmem file descriptor, or -1 9768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Create a Bundle from a map of LibInfo objects. 9798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static Bundle createBundleFromLibInfoMap(HashMap<String, LibInfo> map) { 9808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Bundle bundle = new Bundle(map.size()); 981a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (Map.Entry<String, LibInfo> entry : map.entrySet()) { 9828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bundle.putParcelable(entry.getKey(), entry.getValue()); 983a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 9848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return bundle; 9868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Create a new LibInfo map from a Bundle. 9898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static HashMap<String, LibInfo> createLibInfoMapFromBundle(Bundle bundle) { 9908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) HashMap<String, LibInfo> map = new HashMap<String, LibInfo>(); 9918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (String library : bundle.keySet()) { 992a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LibInfo libInfo = bundle.getParcelable(library); 993a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) map.put(library, libInfo); 9948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return map; 9968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 9978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 9988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Call the close() method on all values of a LibInfo map. 9998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static void closeLibInfoMap(HashMap<String, LibInfo> map) { 1000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (Map.Entry<String, LibInfo> entry : map.entrySet()) { 10018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) entry.getValue().close(); 1002a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 10038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 10048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The map of libraries that are currently loaded in this process. 10068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private static HashMap<String, LibInfo> sLoadedLibraries = null; 10078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Used to pass the shared RELRO Bundle through Binder. 10098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public static final String EXTRA_LINKER_SHARED_RELROS = 10108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "org.chromium.content.common.linker.shared_relros"; 10118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1012