OSDN Git Service

PackageManager: Fix reference profile canonicalization.
authorNarayan Kamath <narayan@google.com>
Mon, 16 May 2016 16:34:48 +0000 (17:34 +0100)
committerNarayan Kamath <narayan@google.com>
Wed, 18 May 2016 12:33:56 +0000 (12:33 +0000)
Foreign dex markers are named in the runtime by calling realpath(3) on the input
dexfile path and replacing "/" with "@". On the Java side, we're using
File.getCanonicalPath, which is similar but isn't quite the same. It tries
to call realpath() directly, but if that fails, it resorts to a series of
increasingly desperate measures to calculate a "canonical path". We just
use realpath instead.

Also, don't attempt to delete a profile if canonicalization fails.

bug: 28740848
Change-Id: Ie5d5af590187e793db633342a42b923865e5c005

services/core/java/com/android/server/pm/PackageDexOptimizer.java
services/core/java/com/android/server/pm/PackageManagerService.java
services/core/java/com/android/server/pm/PackageManagerServiceUtils.java

index 89747b5..26a840d 100644 (file)
@@ -328,10 +328,11 @@ class PackageDexOptimizer {
 
         for (String apkPath : pkg.getAllCodePathsExcludingResourceOnly()) {
             try {
-                apkPath = new File(apkPath).getCanonicalPath();
+                apkPath = PackageManagerServiceUtils.realpath(new File(apkPath));
             } catch (IOException e) {
                 // Log an error but continue without it.
                 Slog.w(TAG, "Failed to get canonical path", e);
+                continue;
             }
             String useMarker = apkPath.replace('/', '@');
             final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
index faec844..488645d 100644 (file)
@@ -7603,10 +7603,11 @@ public class PackageManagerService extends IPackageManager.Stub {
 
         for (String path : pkg.getAllCodePathsExcludingResourceOnly()) {
             try {
-                path = new File(path).getCanonicalPath();
+                path = PackageManagerServiceUtils.realpath(new File(path));
             } catch (IOException e) {
                 // TODO: Should we return early here ?
                 Slog.w(TAG, "Failed to get canonical path", e);
+                continue;
             }
 
             final String useMarker = path.replace('/', '@');
index 67cbcd8..b305ba7 100644 (file)
@@ -25,9 +25,13 @@ import android.content.pm.PackageParser;
 import android.content.pm.ResolveInfo;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.system.ErrnoException;
 import android.util.ArraySet;
 import android.util.Log;
+import libcore.io.Libcore;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
@@ -163,4 +167,16 @@ public class PackageManagerServiceUtils {
 
         return result;
     }
-}
\ No newline at end of file
+
+    /**
+     * Returns the canonicalized path of {@code path} as per {@code realpath(3)}
+     * semantics.
+     */
+    public static String realpath(File path) throws IOException {
+        try {
+            return Libcore.os.realpath(path.getAbsolutePath());
+        } catch (ErrnoException ee) {
+            throw ee.rethrowAsIOException();
+        }
+    }
+}