Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf023589 authored by Kenny Root's avatar Kenny Root
Browse files

Fix some problems with ASECs

On devices that had external storage, permissions weren't set correctly
on non-forward-locked applications. Also, moving forward locked
applications didn't work since DefaultContainerService wasn't able to
read it.

Fixed some faulty unit tests as well.

Bug: 6427212
Change-Id: I5c1f0bf5278549069c78939f0708c4c43a7d4006
parent e849230f
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -1229,9 +1229,8 @@ public class PackageManagerTests extends AndroidTestCase {

        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
                PackageManager.INSTALL_FORWARD_LOCK |
                PackageManager.INSTALL_EXTERNAL, true, true,
                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
                PackageManager.INSTALL_EXTERNAL, true, false, -1,
                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
    }

    @LargeTest
@@ -1626,8 +1625,8 @@ public class PackageManagerTests extends AndroidTestCase {

        int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
        int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
        boolean fail = true;
        int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
        boolean fail = false;
        int result = PackageManager.MOVE_SUCCEEDED;
        sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
    }

@@ -1950,7 +1949,7 @@ public class PackageManagerTests extends AndroidTestCase {
                PackageManager.INSTALL_FORWARD_LOCK,
                true,
                false, -1,
                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
                PackageInfo.INSTALL_LOCATION_AUTO);
    }

    /* The following test functions verify install location for existing apps.
+9 −2
Original line number Diff line number Diff line
@@ -311,6 +311,14 @@ public class DefaultContainerService extends IntentService {
            return null;
        }

        try {
            Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
        } catch (ErrnoException e) {
            Slog.e(TAG, "Could not chown APK: " + e.getMessage());
            PackageHelper.destroySdDir(newCid);
            return null;
        }

        if (isForwardLocked) {
            File publicZipFile = new File(newCachePath, publicResFileName);
            try {
@@ -326,10 +334,9 @@ public class DefaultContainerService extends IntentService {
            }

            try {
                Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
                Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644);
            } catch (ErrnoException e) {
                Slog.e(TAG, "Could not chown APK or resource file: " + e.getMessage());
                Slog.e(TAG, "Could not chown public resource file: " + e.getMessage());
                PackageHelper.destroySdDir(newCid);
                return null;
            }
+117 −22
Original line number Diff line number Diff line
@@ -5863,9 +5863,28 @@ public class PackageManagerService extends IPackageManager.Stub {
                Log.w(TAG, "Insufficient storage to install");
                return;
            }
            // Create the file args now.

            mRet = srcArgs.doPreCopy();
            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
                return;
            }

            mRet = targetArgs.copyApk(mContainerService, false);
            targetArgs.doPreInstall(mRet);
            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
                srcArgs.doPostCopy(uid);
                return;
            }

            mRet = srcArgs.doPostCopy(uid);
            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
                return;
            }

            mRet = targetArgs.doPreInstall(mRet);
            if (mRet != PackageManager.INSTALL_SUCCEEDED) {
                return;
            }

            if (DEBUG_SD_INSTALL) {
                StringBuilder builder = new StringBuilder();
                if (srcArgs != null) {
@@ -5936,7 +5955,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            String nativeLibraryPath) {
        if (installOnSd(flags) || installForwardLocked(flags)) {
            return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
                    (flags & PackageManager.INSTALL_EXTERNAL) != 0);
                    installOnSd(flags), installForwardLocked(flags));
        } else {
            return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
        }
@@ -5945,9 +5964,10 @@ public class PackageManagerService extends IPackageManager.Stub {
    // Used by package mover
    private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
        if (installOnSd(flags) || installForwardLocked(flags)) {
            String cid = getNextCodePath(null, pkgName, "/" + AsecInstallArgs.RES_FILE_NAME);
            return new AsecInstallArgs(packageURI, cid,
                    (flags & PackageManager.INSTALL_EXTERNAL) != 0);
            String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
                    + AsecInstallArgs.RES_FILE_NAME);
            return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
                    installForwardLocked(flags));
        } else {
            return new FileInstallArgs(packageURI, pkgName, dataDir);
        }
@@ -5984,6 +6004,26 @@ public class PackageManagerService extends IPackageManager.Stub {
        abstract boolean doPostDeleteLI(boolean delete);
        abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;

        /**
         * Called before the source arguments are copied. This is used mostly
         * for MoveParams when it needs to read the source file to put it in the
         * destination.
         */
        int doPreCopy() {
            return PackageManager.INSTALL_SUCCEEDED;
        }

        /**
         * Called after the source arguments are copied. This is used mostly for
         * MoveParams when it needs to read the source file to put it in the
         * destination.
         *
         * @return
         */
        int doPostCopy(int uid) {
            return PackageManager.INSTALL_SUCCEEDED;
        }

        protected boolean isFwdLocked() {
            return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
        }
@@ -6280,8 +6320,9 @@ public class PackageManagerService extends IPackageManager.Stub {
        }

        AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
                boolean isExternal) {
            super(null, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null);
                boolean isExternal, boolean isForwardLocked) {
            super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null);
            // Extract cid from fullCodePath
            int eidx = fullCodePath.lastIndexOf("/");
            String subStr1 = fullCodePath.substring(0, eidx);
@@ -6296,8 +6337,9 @@ public class PackageManagerService extends IPackageManager.Stub {
            setCachePath(PackageHelper.getSdDir(cid));
        }

        AsecInstallArgs(Uri packageURI, String cid, boolean isExternal) {
            super(packageURI, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null);
        AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
            super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
                    | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null);
            this.cid = cid;
        }

@@ -6443,8 +6485,18 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp();
            } else {
                final int groupOwner;
                final String protectedFile;
                if (isFwdLocked()) {
                    groupOwner = uid;
                    protectedFile = RES_FILE_NAME;
                } else {
                    groupOwner = -1;
                    protectedFile = null;
                }

                if (uid < Process.FIRST_APPLICATION_UID
                        || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) {
                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
                    Slog.e(TAG, "Failed to finalize " + cid);
                    PackageHelper.destroySdDir(cid);
                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
@@ -6505,6 +6557,33 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            return ret;
        }

        @Override
        int doPreCopy() {
            if (isFwdLocked()) {
                if (!PackageHelper.fixSdPermissions(cid,
                        getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
                }
            }

            return PackageManager.INSTALL_SUCCEEDED;
        }

        @Override
        int doPostCopy(int uid) {
            if (isFwdLocked()) {
                PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME);
                if (uid < Process.FIRST_APPLICATION_UID
                        || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) {
                    Slog.e(TAG, "Failed to finalize " + cid);
                    PackageHelper.destroySdDir(cid);
                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
                }
            }

            return PackageManager.INSTALL_SUCCEEDED;
        }
    };

    // Utility method used to create code paths based on package name and available index.
@@ -8696,9 +8775,15 @@ public class PackageManagerService extends IPackageManager.Stub {
                                : PackageManager.INSTALL_INTERNAL;
                        currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
                                : PackageManager.INSTALL_INTERNAL;

                        if (newFlags == currFlags) {
                            Slog.w(TAG, "No move required. Trying to move to same location");
                            returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
                        } else {
                            if (isForwardLocked(pkg)) {
                                currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
                                newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
                            }
                        }
                    }
                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
@@ -8784,13 +8869,19 @@ public class PackageManagerService extends IPackageManager.Stub {
                                    final String newNativePath = mp.targetArgs
                                            .getNativeLibraryPath();

                                    if ((mp.flags & PackageManager.INSTALL_EXTERNAL) == 0) {
                                    try {
                                        final File newNativeDir = new File(newNativePath);

                                        final String libParentDir = newNativeDir.getParentFile()
                                                .getCanonicalPath();
                                        if (newNativeDir.getParentFile().getCanonicalPath()
                                                .equals(pkg.applicationInfo.dataDir)) {
                                            if (mInstaller
                                                    .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
                                            } else {
                                            NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
                                                    newCodePath), new File(newNativePath));
                                                NativeLibraryHelper.copyNativeBinariesIfNeededLI(
                                                        new File(newCodePath), newNativeDir);
                                            }
                                        } else {
                                            if (mInstaller.linkNativeLibraryDirectory(
@@ -8798,6 +8889,10 @@ public class PackageManagerService extends IPackageManager.Stub {
                                                returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
                                            }
                                        }
                                    } catch (IOException e) {
                                        returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
                                    }


                                    if (returnCode == PackageManager.MOVE_SUCCEEDED) {
                                        pkg.mPath = newCodePath;