Provide libraryPermittedPath to android runtime
Opening native libraries in isolated namespaces is limited to
the search-path (librarySearchPath). The libraryPermittedPath allows
to expand the list of allowed directories for isolated namespaces.
Bug: http://b/22548808
Bug: http://b/25853516
Change-Id: Id229be7760c3c47b7307452493bbb8bdf3faabb7
(cherry picked from commit a2656629522f9d79e2dca7418ab5963f50d0fda8)
diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
index 5ef00bf..0e112fc 100644
--- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
@@ -37,15 +37,46 @@
* defaults to {@code ":"} on Android
* @param optimizedDirectory directory where optimized dex files
* should be written; may be {@code null}
- * @param libraryPath the list of directories containing native
+ * @param librarySearchPath the list of directories containing native
* libraries, delimited by {@code File.pathSeparator}; may be
* {@code null}
* @param parent the parent class loader
+ *
+ * This method will be deprecated in the next release
*/
public BaseDexClassLoader(String dexPath, File optimizedDirectory,
- String libraryPath, ClassLoader parent) {
+ String librarySearchPath, ClassLoader parent) {
+ this(dexPath, optimizedDirectory, librarySearchPath, null, parent);
+ }
+
+ /**
+ * Constructs an instance.
+ *
+ * @param dexPath the list of jar/apk files containing classes and
+ * resources, delimited by {@code File.pathSeparator}, which
+ * defaults to {@code ":"} on Android
+ * @param optimizedDirectory directory where optimized dex files
+ * should be written; may be {@code null}
+ * @param librarySearchPath the list of directories containing native
+ * libraries, delimited by {@code File.pathSeparator}; may be
+ * {@code null}; directories in this list are used to search for
+ * a native library
+ * @param libraryPermittedPath allows opening native libraries under
+ * directories in this list. The list is delimited by
+ * {@code File.pathSeparator}. Note that the classloader
+ * is implicitly allowed to open libraries from the
+ * directories on libraryPath. Directories from this list
+ * are NOT used to search for the native library;
+ * may be {@code null}
+ * @param parent the parent class loader
+ *
+ * @hide
+ */
+ public BaseDexClassLoader(String dexPath, File optimizedDirectory,
+ String librarySearchPath, String libraryPermittedPath, ClassLoader parent) {
super(parent);
- this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
+ this.pathList = new DexPathList(this, dexPath, librarySearchPath,
+ libraryPermittedPath, optimizedDirectory);
}
@Override
@@ -134,6 +165,13 @@
return result.toString();
}
+ /**
+ * @hide
+ */
+ public String getLibraryPermittedPath() {
+ return pathList.getLibraryPermittedPath();
+ }
+
@Override public String toString() {
return getClass().getName() + "[" + pathList + "]";
}
diff --git a/dalvik/src/main/java/dalvik/system/DexClassLoader.java b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
index a645f42..4bbdbd8 100644
--- a/dalvik/src/main/java/dalvik/system/DexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
@@ -47,13 +47,48 @@
* defaults to {@code ":"} on Android
* @param optimizedDirectory directory where optimized dex files
* should be written; must not be {@code null}
- * @param libraryPath the list of directories containing native
+ * @param librarySearchPath the list of directories containing native
* libraries, delimited by {@code File.pathSeparator}; may be
* {@code null}
* @param parent the parent class loader
+ *
+ * This method will be deprecated in the next release
*/
public DexClassLoader(String dexPath, String optimizedDirectory,
- String libraryPath, ClassLoader parent) {
- super(dexPath, new File(optimizedDirectory), libraryPath, parent);
+ String librarySearchPath, ClassLoader parent) {
+ super(dexPath, new File(optimizedDirectory), librarySearchPath, null, parent);
+ }
+
+ /**
+ * Creates a {@code DexClassLoader} that finds interpreted and native
+ * code. Interpreted classes are found in a set of DEX files contained
+ * in Jar or APK files.
+ *
+ * <p>The path lists are separated using the character specified by the
+ * {@code path.separator} system property, which defaults to {@code :}.
+ *
+ * @param dexPath the list of jar/apk files containing classes and
+ * resources, delimited by {@code File.pathSeparator}, which
+ * defaults to {@code ":"} on Android
+ * @param optimizedDirectory directory where optimized dex files
+ * should be written; must not be {@code null}
+ * @param librarySearchPath the list of directories containing native
+ * libraries, delimited by {@code File.pathSeparator}; may be
+ * {@code null}
+ * @param libraryPermittedPath Allowing open native libraries under
+ * directories in this list. The list is delimited by
+ * {@code File.pathSeparator}. Note that the classloader
+ * is implicitly allowed to open libraries from the
+ * directories on librarySearchPath. Directories from this list
+ * are NOT used to search for the native library;
+ * may be {@code null}
+ * @param parent the parent class loader
+ *
+ * @hide
+ */
+ public DexClassLoader(String dexPath, String optimizedDirectory,
+ String librarySearchPath, String libraryPermittedPath, ClassLoader parent) {
+ super(dexPath, new File(optimizedDirectory), librarySearchPath,
+ libraryPermittedPath, parent);
}
}
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index d4f80e9..e9a73de 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -70,6 +70,9 @@
/** List of system native library directories. */
private final List<File> systemNativeLibraryDirectories;
+ /** The permitted library path for classloader-namespaces */
+ private final String libraryPermittedPath;
+
/**
* Exceptions thrown during creation of the dexElements list.
*/
@@ -82,14 +85,19 @@
* classes should be defined
* @param dexPath list of dex/resource path elements, separated by
* {@code File.pathSeparator}
- * @param libraryPath list of native library directory path elements,
+ * @param librarySearchPath list of native library directory path elements,
* separated by {@code File.pathSeparator}
+ * @param libraryPermittedPath is path containing permitted directories for
+ * linker isolated namespaces (in addition to librarySearchPath which is allowed
+ * implicitly). Note that this path does not affect the search order for the library
+ * and intended for white-listing additional paths when loading native libraries
+ * by absolute path.
* @param optimizedDirectory directory where optimized {@code .dex} files
* should be found and written to, or {@code null} to use the default
* system directory for same
*/
public DexPathList(ClassLoader definingContext, String dexPath,
- String libraryPath, File optimizedDirectory) {
+ String librarySearchPath, String libraryPermittedPath, File optimizedDirectory) {
if (definingContext == null) {
throw new NullPointerException("definingContext == null");
@@ -124,14 +132,14 @@
// Native libraries may exist in both the system and
// application library paths, and we use this search order:
//
- // 1. This class loader's library path for application libraries (libraryPath):
+ // 1. This class loader's library path for application libraries (librarySearchPath):
// 1.1. Native library directories
// 1.2. Path to libraries in apk-files
// 2. The VM's library path from the system property for system libraries
// also known as java.library.path
//
// This order was reversed prior to Gingerbread; see http://b/2933456.
- this.nativeLibraryDirectories = splitPaths(libraryPath, false);
+ this.nativeLibraryDirectories = splitPaths(librarySearchPath, false);
this.systemNativeLibraryDirectories =
splitPaths(System.getProperty("java.library.path"), true);
List<File> allNativeLibraryDirectories = new ArrayList<>(nativeLibraryDirectories);
@@ -147,6 +155,8 @@
} else {
dexElementsSuppressedExceptions = null;
}
+
+ this.libraryPermittedPath = libraryPermittedPath;
}
@Override public String toString() {
@@ -169,6 +179,13 @@
}
/**
+ * For BaseDexClassLoader.getLibraryPermittedPath.
+ */
+ public String getLibraryPermittedPath() {
+ return libraryPermittedPath;
+ }
+
+ /**
* Splits the given dex path string into elements using the path
* separator, pruning out any elements that do not refer to existing
* and readable files.
diff --git a/dalvik/src/main/java/dalvik/system/PathClassLoader.java b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
index 32c5586..83b4366 100644
--- a/dalvik/src/main/java/dalvik/system/PathClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
@@ -35,7 +35,7 @@
* @param parent the parent class loader
*/
public PathClassLoader(String dexPath, ClassLoader parent) {
- super(dexPath, null, null, parent);
+ super(dexPath, null, null, null, parent);
}
/**
@@ -55,13 +55,48 @@
* @param dexPath the list of jar/apk files containing classes and
* resources, delimited by {@code File.pathSeparator}, which
* defaults to {@code ":"} on Android
- * @param libraryPath the list of directories containing native
+ * @param librarySearchPath the list of directories containing native
* libraries, delimited by {@code File.pathSeparator}; may be
* {@code null}
* @param parent the parent class loader
+ *
+ * This method will be deprecated in the next release
*/
- public PathClassLoader(String dexPath, String libraryPath,
+ public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
+ super(dexPath, null, librarySearchPath, null, parent);
+ }
+
+ /**
+ * Creates a {@code PathClassLoader} that operates on two given
+ * lists of files and directories. The entries of the first list
+ * should be one of the following:
+ *
+ * <ul>
+ * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file as
+ * well as arbitrary resources.
+ * <li>Raw ".dex" files (not inside a zip file).
+ * </ul>
+ *
+ * The entries of the second list should be directories containing
+ * native library files.
+ *
+ * @param dexPath the list of jar/apk files containing classes and
+ * resources, delimited by {@code File.pathSeparator}, which
+ * defaults to {@code ":"} on Android
+ * @param librarySearchPath the list of directories containing native
+ * libraries, delimited by {@code File.pathSeparator}; may be
+ * {@code null}
+ * @param libraryPermittedPath allowing to open native libraries under
+ * directories in this list. The list is delimited by {@code File.pathSeparator}.
+ * Note that the classloader is implicitly allowed to open libraries from the
+ * directories on librarySearchPath. Directories from this list are NOT used
+ * to search for the native library; may be {@code null}
+ * @param parent the parent class loader
+ *
+ * @hide
+ */
+ public PathClassLoader(String dexPath, String librarySearchPath, String libraryPermittedPath,
ClassLoader parent) {
- super(dexPath, null, libraryPath, parent);
+ super(dexPath, null, librarySearchPath, libraryPermittedPath, parent);
}
}