diff options
-rw-r--r-- | core/java/android/app/LoadedApk.java | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 1dc54ddbac4b..aa6a08b6d2e4 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -814,12 +814,9 @@ public final class LoadedApk { makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths); - String libraryPermittedPath = mDataDir; - if (mActivityThread == null) { - // In a zygote context where mActivityThread is null we can't access the app data dir - // and including this in libraryPermittedPath would cause SELinux denials. - libraryPermittedPath = ""; - } + // Including an inaccessible dir in libraryPermittedPath would cause SELinux denials + // when the loader attempts to canonicalise the path. so we don't. + String libraryPermittedPath = canAccessDataDir() ? mDataDir : ""; if (isBundledApp) { // For bundled apps, add the base directory of the app (e.g., @@ -972,6 +969,33 @@ public final class LoadedApk { } } + /** + * Return whether we can access the package's private data directory in order to be able to + * load code from it. + */ + private boolean canAccessDataDir() { + // In a zygote context where mActivityThread is null we can't access the app data dir. + if (mActivityThread == null) { + return false; + } + + // A package can access its own data directory (the common case, so short-circuit it). + if (Objects.equals(mPackageName, ActivityThread.currentPackageName())) { + return true; + } + + // Temporarily disable logging of disk reads on the Looper thread as this is necessary - + // and the loader will access the directory anyway if we don't check it. + StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads(); + try { + // We are constructing a classloader for a different package. It is likely, + // but not certain, that we can't acccess its app data dir - so check. + return new File(mDataDir).canExecute(); + } finally { + setThreadPolicy(oldPolicy); + } + } + @UnsupportedAppUsage public ClassLoader getClassLoader() { synchronized (this) { |