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

Commit eb922e64 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Add facility to limit associations that are allowed between apps."

parents 7c73eca4 769b2e75
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -445,8 +445,18 @@ public final class AssociationState {
        }
    }

    public boolean hasProcess(String procName) {
        final int NSRC = mSources.size();
        for (int isrc = 0; isrc < NSRC; isrc++) {
            if (mSources.keyAt(isrc).mProcess.equals(procName)) {
                return true;
            }
        }
        return false;
    }

    public void dumpStats(PrintWriter pw, String prefix, String prefixInner, String headerPrefix,
            long now, long totalTime, boolean dumpDetails, boolean dumpAll) {
            long now, long totalTime, String reqPackage, boolean dumpDetails, boolean dumpAll) {
        if (dumpAll) {
            pw.print(prefix);
            pw.print("mNumActive=");
@@ -456,6 +466,9 @@ public final class AssociationState {
        for (int isrc = 0; isrc < NSRC; isrc++) {
            final SourceKey key = mSources.keyAt(isrc);
            final SourceState src = mSources.valueAt(isrc);
            if (reqPackage != null && !reqPackage.equals(key.mProcess)) {
                continue;
            }
            pw.print(prefixInner);
            pw.print("<- ");
            pw.print(key.mProcess);
+20 −5
Original line number Diff line number Diff line
@@ -1475,6 +1475,7 @@ public final class ProcessStats implements Parcelable {
                        final int NSRVS = pkgState.mServices.size();
                        final int NASCS = pkgState.mAssociations.size();
                        final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
                        boolean onlyAssociations = false;
                        if (!pkgMatch) {
                            boolean procMatch = false;
                            for (int iproc = 0; iproc < NPROCS; iproc++) {
@@ -1485,9 +1486,20 @@ public final class ProcessStats implements Parcelable {
                                }
                            }
                            if (!procMatch) {
                                // Check if this app has any associations with the requested
                                // package, so that if so we print those.
                                for (int iasc = 0; iasc < NASCS; iasc++) {
                                    AssociationState asc = pkgState.mAssociations.valueAt(iasc);
                                    if (asc.hasProcess(reqPackage)) {
                                        onlyAssociations = true;
                                        break;
                                    }
                                }
                                if (!onlyAssociations) {
                                    continue;
                                }
                            }
                        }
                        if (NPROCS > 0 || NSRVS > 0 || NASCS > 0) {
                            if (!printedHeader) {
                                if (sepNeeded) pw.println();
@@ -1503,7 +1515,7 @@ public final class ProcessStats implements Parcelable {
                            pw.print(vers);
                            pw.println(":");
                        }
                        if ((section & REPORT_PKG_PROC_STATS) != 0) {
                        if ((section & REPORT_PKG_PROC_STATS) != 0 && !onlyAssociations) {
                            if (!dumpSummary || dumpAll) {
                                for (int iproc = 0; iproc < NPROCS; iproc++) {
                                    ProcessState proc = pkgState.mProcesses.valueAt(iproc);
@@ -1550,7 +1562,7 @@ public final class ProcessStats implements Parcelable {
                                        now, totalTime);
                            }
                        }
                        if ((section & REPORT_PKG_SVC_STATS) != 0) {
                        if ((section & REPORT_PKG_SVC_STATS) != 0 && !onlyAssociations) {
                            for (int isvc = 0; isvc < NSRVS; isvc++) {
                                ServiceState svc = pkgState.mServices.valueAt(isvc);
                                if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) {
@@ -1579,8 +1591,10 @@ public final class ProcessStats implements Parcelable {
                            for (int iasc = 0; iasc < NASCS; iasc++) {
                                AssociationState asc = pkgState.mAssociations.valueAt(iasc);
                                if (!pkgMatch && !reqPackage.equals(asc.getProcessName())) {
                                    if (!onlyAssociations || !asc.hasProcess(reqPackage)) {
                                        continue;
                                    }
                                }
                                if (activeOnly && !asc.isInUse()) {
                                    pw.print("      (Not active association: ");
                                    pw.print(pkgState.mAssociations.keyAt(iasc));
@@ -1597,7 +1611,8 @@ public final class ProcessStats implements Parcelable {
                                pw.print("        Process: ");
                                pw.println(asc.getProcessName());
                                asc.dumpStats(pw, "        ", "          ", "    ",
                                        now, totalTime, dumpDetails, dumpAll);
                                        now, totalTime, onlyAssociations ? reqPackage : null,
                                        dumpDetails, dumpAll);
                            }
                        }
                    }
+442 −294

File changed.

Preview size limit exceeded, changes collapsed.

+18 −5
Original line number Diff line number Diff line
@@ -2019,6 +2019,13 @@ public final class ActiveServices {
                ComponentName className = new ComponentName(
                        sInfo.applicationInfo.packageName, sInfo.name);
                ComponentName name = comp != null ? comp : className;
                if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid,
                        name.getPackageName(), sInfo.applicationInfo.uid)) {
                    String msg = "association not allowed between packages "
                            + callingPackage + " and " + r.packageName;
                    Slog.w(TAG, "Service lookup failed: " + msg);
                    return new ServiceLookupResult(null, msg);
                }
                if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
                    if (isBindExternal) {
                        if (!sInfo.exported) {
@@ -2099,6 +2106,17 @@ public final class ActiveServices {
            }
        }
        if (r != null) {
            if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid, r.packageName,
                    r.appInfo.uid)) {
                String msg = "association not allowed between packages "
                        + callingPackage + " and " + r.packageName;
                Slog.w(TAG, "Service lookup failed: " + msg);
                return new ServiceLookupResult(null, msg);
            }
            if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                    resolvedType, r.appInfo)) {
                return new ServiceLookupResult(null, "blocked by firewall");
            }
            if (mAm.checkComponentPermission(r.permission,
                    callingPid, callingUid, r.appInfo.uid, r.exported) != PERMISSION_GRANTED) {
                if (!r.exported) {
@@ -2125,11 +2143,6 @@ public final class ActiveServices {
                    return null;
                }
            }

            if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                    resolvedType, r.appInfo)) {
                return null;
            }
            return new ServiceLookupResult(r, null);
        }
        return null;
+116 −0
Original line number Diff line number Diff line
@@ -657,6 +657,12 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    ArraySet<String> mBackgroundLaunchBroadcasts;
    /**
     * When an app has restrictions on the other apps that can have associations with it,
     * it appears here with a set of the allowed apps.
     */
    ArrayMap<String, ArraySet<String>> mAllowedAssociations;
    /**
     * All of the processes we currently have running organized by pid.
     * The keys are the pid running the application.
@@ -2396,6 +2402,34 @@ public class ActivityManagerService extends IActivityManager.Stub
        return mBackgroundLaunchBroadcasts;
    }
    boolean validateAssociationAllowedLocked(String pkg1, int uid1, String pkg2, int uid2) {
        if (mAllowedAssociations == null) {
            mAllowedAssociations = SystemConfig.getInstance().getAllowedAssociations();
        }
        // Interactions with the system uid are always allowed, since that is the core system
        // that everyone needs to be able to interact with.
        if (UserHandle.getAppId(uid1) == SYSTEM_UID) {
            return true;
        }
        if (UserHandle.getAppId(uid2) == SYSTEM_UID) {
            return true;
        }
        // We won't allow this association if either pkg1 or pkg2 has a limit on the
        // associations that are allowed with it, and the other package is not explicitly
        // specified as one of those associations.
        ArraySet<String> pkgs = mAllowedAssociations.get(pkg1);
        if (pkgs != null) {
            if (!pkgs.contains(pkg2)) {
                return false;
            }
        }
        pkgs = mAllowedAssociations.get(pkg2);
        if (pkgs != null) {
            return pkgs.contains(pkg1);
        }
        return true;
    }
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
@@ -6264,6 +6298,21 @@ public class ActivityManagerService extends IActivityManager.Stub
        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
    }
    private String checkContentProviderAssociation(ProcessRecord callingApp, int callingUid,
            ProviderInfo cpi) {
        if (callingApp == null) {
            return validateAssociationAllowedLocked(cpi.packageName, cpi.applicationInfo.uid,
                    null, callingUid) ? null : "<null>";
        }
        for (int i = callingApp.pkgList.size() - 1; i >= 0; i--) {
            if (!validateAssociationAllowedLocked(callingApp.pkgList.keyAt(i), callingApp.uid,
                    cpi.packageName, cpi.applicationInfo.uid)) {
                return cpi.packageName;
            }
        }
        return null;
    }
    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
            String name, IBinder token, int callingUid, String callingTag, boolean stable,
            int userId) {
@@ -6335,6 +6384,11 @@ public class ActivityManagerService extends IActivityManager.Stub
                String msg;
                if (r != null && cpr.canRunHere(r)) {
                    if ((msg = checkContentProviderAssociation(r, callingUid, cpi)) != null) {
                        throw new SecurityException("Content provider lookup "
                                + cpr.name.flattenToShortString()
                                + " failed: association not allowed with package " + msg);
                    }
                    checkTime(startTime,
                            "getContentProviderImpl: before checkContentProviderPermission");
                    if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
@@ -6364,6 +6418,11 @@ public class ActivityManagerService extends IActivityManager.Stub
                } catch (RemoteException e) {
                }
                if ((msg = checkContentProviderAssociation(r, callingUid, cpi)) != null) {
                    throw new SecurityException("Content provider lookup "
                            + cpr.name.flattenToShortString()
                            + " failed: association not allowed with package " + msg);
                }
                checkTime(startTime,
                        "getContentProviderImpl: before checkContentProviderPermission");
                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
@@ -6461,6 +6520,11 @@ public class ActivityManagerService extends IActivityManager.Stub
                checkTime(startTime, "getContentProviderImpl: got app info for user");
                String msg;
                if ((msg = checkContentProviderAssociation(r, callingUid, cpi)) != null) {
                    throw new SecurityException("Content provider lookup "
                            + cpr.name.flattenToShortString()
                            + " failed: association not allowed with package " + msg);
                }
                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
                        != null) {
@@ -9206,6 +9270,12 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
            }
            dumpAllowedAssociationsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
            pw.println();
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
            }
            mPendingIntentController.dumpPendingIntents(pw, dumpAll, dumpPackage);
            pw.println();
@@ -9474,6 +9544,14 @@ public class ActivityManagerService extends IActivityManager.Stub
                    System.gc();
                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
                }
            } else if ("allowed-associations".equals(cmd)) {
                if (opti < args.length) {
                    dumpPackage = args[opti];
                    opti++;
                }
                synchronized (this) {
                    dumpAllowedAssociationsLocked(fd, pw, args, opti, true, dumpPackage);
                }
            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
                if (opti < args.length) {
                    dumpPackage = args[opti];
@@ -10824,6 +10902,44 @@ public class ActivityManagerService extends IActivityManager.Stub
        proto.end(handlerToken);
    }
    void dumpAllowedAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll, String dumpPackage) {
        boolean needSep = false;
        boolean printedAnything = false;
        pw.println("ACTIVITY MANAGER ALLOWED ASSOCIATION STATE (dumpsys activity allowed-associations)");
        boolean printed = false;
        if (mAllowedAssociations != null) {
            for (int i = 0; i < mAllowedAssociations.size(); i++) {
                final String pkg = mAllowedAssociations.keyAt(i);
                final ArraySet<String> asc = mAllowedAssociations.valueAt(i);
                boolean printedHeader = false;
                for (int j = 0; j < asc.size(); j++) {
                    if (dumpPackage == null || pkg.equals(dumpPackage)
                            || asc.valueAt(j).equals(dumpPackage)) {
                        if (!printed) {
                            pw.println("  Allowed associations (by restricted package):");
                            printed = true;
                            needSep = true;
                            printedAnything = true;
                        }
                        if (!printedHeader) {
                            pw.print("  * ");
                            pw.print(pkg);
                            pw.println(":");
                            printedHeader = true;
                        }
                        pw.print("      Allow: ");
                        pw.println(asc.valueAt(j));
                    }
                }
            }
        }
        if (!printed) {
            pw.println("  (No association restrictions)");
        }
    }
    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll, String dumpPackage) {
        boolean needSep = false;
Loading