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

Commit fc0839ae authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Work on issue #143085640: Per-process network access control

Fix some issues when apps start declaring processes, add validation
that apps don't use processes they haven't declared (if they
declared some).  Also add package dump output for the processes it
has declared.

Bug: 143085640
Test: atest CtsAppSecurityHostTestCases:UseProcessTest
Change-Id: If1d13bf402d2b0aea06f0c2c02d5e392c774c812
parent 981f524a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1506,6 +1506,15 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_FAILED_WRONG_INSTALLED_VERSION = -121;

    /**
     * Installation return code: this is passed in the {@link PackageInstaller#EXTRA_LEGACY_STATUS}
     * if the new package failed because it contains a request to use a process that was not
     * explicitly defined as part of its <processes> tag.
     *
     * @hide
     */
    public static final int INSTALL_FAILED_PROCESS_NOT_DEFINED = -122;

    /** @hide */
    @IntDef(flag = true, prefix = { "DELETE_" }, value = {
            DELETE_KEEP_DATA,
@@ -7237,6 +7246,7 @@ public abstract class PackageManager {
            case INSTALL_FAILED_MISSING_SPLIT: return "INSTALL_FAILED_MISSING_SPLIT";
            case INSTALL_FAILED_BAD_SIGNATURE: return "INSTALL_FAILED_BAD_SIGNATURE";
            case INSTALL_FAILED_WRONG_INSTALLED_VERSION: return "INSTALL_FAILED_WRONG_INSTALLED_VERSION";
            case INSTALL_FAILED_PROCESS_NOT_DEFINED: return "INSTALL_FAILED_PROCESS_NOT_DEFINED";
            default: return Integer.toString(status);
        }
    }
+4 −8
Original line number Diff line number Diff line
@@ -3414,16 +3414,12 @@ public class ComponentParseUtils {
            proc.name = sa.getNonConfigurationString(
                    R.styleable.AndroidManifestProcess_process,0);
            proc.name = PackageParser.buildProcessName(parsingPackage.getPackageName(),
                    null, proc.name, flags, separateProcesses, outError);

            if (proc.name == null || proc.name.length() <= 0) {
                outError[0] = "<process> does not specify android:process";
                    parsingPackage.getPackageName(), proc.name, flags, separateProcesses, outError);
            if (outError[0] != null) {
                return null;
            }
            proc.name = PackageParser.buildProcessName(parsingPackage.getPackageName(),
                    parsingPackage.getPackageName(), proc.name,
                    flags, separateProcesses, outError);
            if (outError[0] != null) {
            if (proc.name == null || proc.name.length() <= 0) {
                outError[0] = "<process> does not specify android:process";
                return null;
            }
        } finally {
+10 −3
Original line number Diff line number Diff line
@@ -615,13 +615,20 @@ class ProcessRecord implements WindowProcessListener {
            int _uid) {
        mService = _service;
        info = _info;
        ProcessInfo procInfo = null;
        if (_service.mPackageManagerInt != null) {
            ArrayMap<String, ProcessInfo> processes =
                    _service.mPackageManagerInt.getProcessesForUid(_uid);
            processInfo = processes != null ? processes.get(_processName) : null;
        } else {
            processInfo = null;
            if (processes != null) {
                procInfo = processes.get(_processName);
                if (procInfo != null && procInfo.deniedPermissions == null) {
                    // If this process hasn't asked for permissions to be denied, then
                    // we don't care about it.
                    procInfo = null;
                }
            }
        }
        processInfo = procInfo;
        isolated = _info.uid != _uid;
        appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID
                && UserHandle.getAppId(_uid) <= Process.LAST_APP_ZYGOTE_ISOLATED_UID);
+40 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
import static android.content.pm.PackageManager.INSTALL_FAILED_PROCESS_NOT_DEFINED;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
@@ -205,6 +206,7 @@ import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.dex.IArtManager;
import android.content.pm.parsing.AndroidPackage;
import android.content.pm.parsing.ApkParseUtils;
import android.content.pm.parsing.ComponentParseUtils;
import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
@@ -11246,6 +11248,26 @@ public class PackageManagerService extends IPackageManager.Stub
        return object;
    }
    private <T extends ComponentParseUtils.ParsedMainComponent>
            void assertPackageProcesses(AndroidPackage pkg, List<T> components,
            ArrayMap<String, ComponentParseUtils.ParsedProcess> procs, String compName)
            throws PackageManagerException {
        if (components == null) {
            return;
        }
        for (int i = components.size() - 1; i >= 0; i--) {
            final ComponentParseUtils.ParsedMainComponent<?> component = components.get(i);
            if (!procs.containsKey(component.getProcessName())) {
                throw new PackageManagerException(
                        INSTALL_FAILED_PROCESS_NOT_DEFINED,
                        "Can't install because " + compName + " " + component.className
                                + "'s process attribute " + component.getProcessName()
                                + " (in package " + pkg.getPackageName()
                                + ") is not included in the <processes> list");
            }
        }
    }
    /**
     * Asserts the parsed package is valid according to the given policy. If the
     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
@@ -11475,6 +11497,24 @@ public class PackageManagerService extends IPackageManager.Stub
                mComponentResolver.assertProvidersNotDefined(pkg);
            }
            // If this package has defined explicit processes, then ensure that these are
            // the only processes used by its components.
            final ArrayMap<String, ComponentParseUtils.ParsedProcess> procs = pkg.getProcesses();
            if (procs != null) {
                if (!procs.containsKey(pkg.getProcessName())) {
                    throw new PackageManagerException(
                            INSTALL_FAILED_PROCESS_NOT_DEFINED,
                            "Can't install because application tag's process attribute "
                                    + pkg.getProcessName()
                                    + " (in package " + pkg.getPackageName()
                                    + ") is not included in the <processes> list");
                }
                assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
                assertPackageProcesses(pkg, pkg.getServices(), procs, "service");
                assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver");
                assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider");
            }
            // Verify that packages sharing a user with a privileged app are marked as privileged.
            if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
                SharedUserSetting sharedUserSetting = null;
+20 −6
Original line number Diff line number Diff line
@@ -4564,7 +4564,7 @@ public final class Settings {
                pw.print("anyDensity");
            }
            pw.println("]");
            List<String> libraryNames = pkg.getLibraryNames();
            final List<String> libraryNames = pkg.getLibraryNames();
            if (libraryNames != null && libraryNames.size() > 0) {
                pw.print(prefix); pw.println("  dynamic libraries:");
                for (int i = 0; i< libraryNames.size(); i++) {
@@ -4579,7 +4579,7 @@ public final class Settings {
                pw.print(" version:"); pw.println(pkg.getStaticSharedLibVersion());
            }

            List<String> usesLibraries = pkg.getUsesLibraries();
            final List<String> usesLibraries = pkg.getUsesLibraries();
            if (usesLibraries != null && usesLibraries.size() > 0) {
                pw.print(prefix); pw.println("  usesLibraries:");
                for (int i=0; i< usesLibraries.size(); i++) {
@@ -4587,8 +4587,8 @@ public final class Settings {
                }
            }

            List<String> usesStaticLibraries = pkg.getUsesStaticLibraries();
            long[] usesStaticLibrariesVersions = pkg.getUsesStaticLibrariesVersions();
            final List<String> usesStaticLibraries = pkg.getUsesStaticLibraries();
            final long[] usesStaticLibrariesVersions = pkg.getUsesStaticLibrariesVersions();
            if (usesStaticLibraries != null
                    && usesStaticLibraries.size() > 0) {
                pw.print(prefix); pw.println("  usesStaticLibraries:");
@@ -4599,7 +4599,7 @@ public final class Settings {
                }
            }

            List<String> usesOptionalLibraries = pkg.getUsesOptionalLibraries();
            final List<String> usesOptionalLibraries = pkg.getUsesOptionalLibraries();
            if (usesOptionalLibraries != null
                    && usesOptionalLibraries.size() > 0) {
                pw.print(prefix); pw.println("  usesOptionalLibraries:");
@@ -4609,7 +4609,7 @@ public final class Settings {
                }
            }

            String[] usesLibraryFiles = pkg.getUsesLibraryFiles();
            final String[] usesLibraryFiles = pkg.getUsesLibraryFiles();
            if (usesLibraryFiles != null
                    && usesLibraryFiles.length > 0) {
                pw.print(prefix); pw.println("  usesLibraryFiles:");
@@ -4617,6 +4617,20 @@ public final class Settings {
                    pw.print(prefix); pw.print("    "); pw.println(usesLibraryFiles[i]);
                }
            }
            final ArrayMap<String, ComponentParseUtils.ParsedProcess> procs = pkg.getProcesses();
            if (procs != null) {
                pw.print(prefix); pw.println("  processes:");
                for (int i = 0; i < procs.size(); i++) {
                    final ComponentParseUtils.ParsedProcess proc = procs.valueAt(i);
                    pw.print(prefix); pw.print("    "); pw.println(proc.name);
                    if (proc.deniedPermissions != null) {
                        for (int j = 0; j < proc.deniedPermissions.size(); j++) {
                            pw.print(prefix); pw.print("      deny: ");
                            pw.println(proc.deniedPermissions.valueAt(j));
                        }
                    }
                }
            }
        }
        pw.print(prefix); pw.print("  timeStamp=");
            date.setTime(ps.timeStamp);
Loading