Пример #1
0
  /**
   * Call this method to determine if this chromium project must use this linker. If not,
   * System.loadLibrary() should be used to load libraries instead.
   */
  public static boolean isUsed() {
    // Only GYP targets that are APKs and have the 'use_chromium_linker' variable
    // defined as 1 will use this linker. For all others (the default), the
    // auto-generated NativeLibraries.USE_LINKER variable will be false.
    if (!NativeLibraries.USE_LINKER) return false;

    synchronized (Linker.class) {
      ensureInitializedLocked();
      // At the moment, there is also no point in using this linker if the
      // system does not support RELRO sharing safely.
      return sRelroSharingSupported;
    }
  }
Пример #2
0
  /**
   * Retrieve the base load address of all shared RELRO sections. This also enforces the creation of
   * shared RELRO sections in prepareLibraryLoad(), which can later be retrieved with
   * getSharedRelros().
   *
   * @return a common, random base load address, or 0 if RELRO sharing is disabled.
   */
  public static long getBaseLoadAddress() {
    synchronized (Linker.class) {
      ensureInitializedLocked();
      if (!sInBrowserProcess) {
        Log.w(TAG, "Shared RELRO sections are disabled in this process!");
        return 0;
      }

      setupBaseLoadAddressLocked();
      if (DEBUG)
        Log.i(TAG, String.format(Locale.US, "getBaseLoadAddress() returns 0x%x", sBaseLoadAddress));
      return sBaseLoadAddress;
    }
  }
Пример #3
0
 /**
  * Call this method before loading any libraries to indicate that this process is ready to reuse
  * shared RELRO sections from another one. Typically used when starting service processes.
  *
  * @param baseLoadAddress the base library load address to use.
  */
 public static void initServiceProcess(long baseLoadAddress) {
   if (DEBUG) {
     Log.i(TAG, String.format(Locale.US, "initServiceProcess(0x%x) called", baseLoadAddress));
   }
   synchronized (Linker.class) {
     ensureInitializedLocked();
     sInBrowserProcess = false;
     sBrowserUsesSharedRelro = false;
     if (sRelroSharingSupported) {
       sWaitForSharedRelros = true;
       sBaseLoadAddress = baseLoadAddress;
       sCurrentLoadAddress = baseLoadAddress;
     }
   }
 }
Пример #4
0
  /**
   * Load a native shared library with the Chromium linker. If neither initSharedRelro() or
   * readFromBundle() were called previously, this uses the standard linker (i.e.
   * System.loadLibrary()).
   *
   * @param library The library's base name.
   */
  public static void loadLibrary(String library) {
    if (DEBUG) Log.i(TAG, "loadLibrary: " + library);

    // Don't self-load the linker. This is because the build system is
    // not clever enough to understand that all the libraries packaged
    // in the final .apk don't need to be explicitly loaded.
    // Also deal with the component build that adds a .cr suffix to the name.
    if (library.equals(TAG) || library.equals(TAG + ".cr")) {
      if (DEBUG) Log.i(TAG, "ignoring self-linker load");
      return;
    }

    synchronized (Linker.class) {
      ensureInitializedLocked();

      // Security: Ensure prepareLibraryLoad() was called before.
      // In theory, this can be done lazily here, but it's more consistent
      // to use a pair of functions (i.e. prepareLibraryLoad() + finishLibraryLoad())
      // that wrap all calls to loadLibrary() in the library loader.
      assert sPrepareLibraryLoadCalled;

      String libName = System.mapLibraryName(library);

      if (sLoadedLibraries == null) sLoadedLibraries = new HashMap<String, LibInfo>();

      if (sLoadedLibraries.containsKey(libName)) {
        if (DEBUG) Log.i(TAG, "Not loading " + libName + " twice");
        return;
      }

      LibInfo libInfo = new LibInfo();
      long loadAddress = 0;
      if ((sInBrowserProcess && sBrowserUsesSharedRelro) || sWaitForSharedRelros) {
        // Load the library at a fixed address.
        loadAddress = sCurrentLoadAddress;
      }

      if (!nativeLoadLibrary(libName, loadAddress, libInfo)) {
        String errorMessage = "Unable to load library: " + libName;
        Log.e(TAG, errorMessage);
        throw new UnsatisfiedLinkError(errorMessage);
      }
      // Keep track whether the library has been loaded at the expected load address.
      if (loadAddress != 0 && loadAddress != libInfo.mLoadAddress) sLoadAtFixedAddressFailed = true;

      // Print the load address to the logcat when testing the linker. The format
      // of the string is expected by the Python test_runner script as one of:
      //    BROWSER_LIBRARY_ADDRESS: <library-name> <address>
      //    RENDERER_LIBRARY_ADDRESS: <library-name> <address>
      // Where <library-name> is the library name, and <address> is the hexadecimal load
      // address.
      if (NativeLibraries.ENABLE_LINKER_TESTS) {
        Log.i(
            TAG,
            String.format(
                Locale.US,
                "%s_LIBRARY_ADDRESS: %s %x",
                sInBrowserProcess ? "BROWSER" : "RENDERER",
                libName,
                libInfo.mLoadAddress));
      }

      if (sInBrowserProcess) {
        // Create a new shared RELRO section at the 'current' fixed load address.
        if (!nativeCreateSharedRelro(libName, sCurrentLoadAddress, libInfo)) {
          Log.w(
              TAG,
              String.format(
                  Locale.US,
                  "Could not create shared RELRO for %s at %x",
                  libName,
                  sCurrentLoadAddress));
        } else {
          if (DEBUG)
            Log.i(
                TAG,
                String.format(
                    Locale.US,
                    "Created shared RELRO for %s at %x: %s",
                    libName,
                    sCurrentLoadAddress,
                    libInfo.toString()));
        }
      }

      if (sCurrentLoadAddress != 0) {
        // Compute the next current load address. If sBaseLoadAddress
        // is not 0, this is an explicit library load address. Otherwise,
        // this is an explicit load address for relocated RELRO sections
        // only.
        sCurrentLoadAddress = libInfo.mLoadAddress + libInfo.mLoadSize;
      }

      sLoadedLibraries.put(libName, libInfo);
      if (DEBUG) Log.i(TAG, "Library details " + libInfo.toString());
    }
  }