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

Commit d8d4e7c5 authored by Roman Birg's avatar Roman Birg Committed by Gerrit Code Review
Browse files

PackageManager: make protected-broadcasts permission aware



This extends the <protected-broadcast> mechanism to allow protecting
actions based on a permission for system apps.

For instance:

   <protected-broadcast android:name="ACTION_A"
                        android:permission="PERMISSION_X" />

will restrict intents with action "ACTION_A" to be only sent with
apps holding the "PERMISSION_X" permission. Note that system UIDs will
bypass the permission check and always be allowed, just like the normal
protected-broadcast mechanism.

You must still be a system application to delcare a protected broadcast.

Change-Id: Id25cffd233d400800dcb5249c5f487134e1b4152
Signed-off-by: default avatarRoman Birg <roman@cyngn.com>
parent 1c93b57a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -523,4 +523,7 @@ interface IPackageManager {
    /** Protected Apps */
    boolean isComponentProtected(in String callingPackage, in int callingUid,
    in ComponentName componentName, int userId);

    /** protected broadcast ext */
    boolean isProtectedBroadcastAllowed(in String actionName, in int callingUid);
}
+11 −4
Original line number Diff line number Diff line
@@ -1877,14 +1877,18 @@ public class PackageParser {
                String name = sa.getNonResourceString(
                        com.android.internal.R.styleable.AndroidManifestProtectedBroadcast_name);

                String permission = sa.getNonResourceString(
                        com.android.internal.R.styleable.AndroidManifestProtectedBroadcast_permission);

                sa.recycle();

                if (name != null && (flags&PARSE_IS_SYSTEM) != 0) {
                    if (pkg.protectedBroadcasts == null) {
                        pkg.protectedBroadcasts = new ArrayList<String>();
                        pkg.protectedBroadcasts = new ArrayMap<>();
                    }
                    if (!pkg.protectedBroadcasts.contains(name)) {
                        pkg.protectedBroadcasts.add(name.intern());
                    if (!pkg.protectedBroadcasts.containsKey(name)) {
                        pkg.protectedBroadcasts.put(name.intern(),
                                permission != null ? permission.intern() : null);
                    }
                }

@@ -4519,7 +4523,10 @@ public class PackageParser {

        public final ArrayList<String> requestedPermissions = new ArrayList<String>();

        public ArrayList<String> protectedBroadcasts;
        /**
         * Maps from package -> permission, null for system (default behavior)
         */
        public ArrayMap<String,String> protectedBroadcasts;

        public ArrayList<String> libraryNames = null;
        public ArrayList<String> usesLibraries = null;
+1 −0
Original line number Diff line number Diff line
@@ -1595,6 +1595,7 @@
         {@link #AndroidManifest manifest} tag. -->
    <declare-styleable name="AndroidManifestProtectedBroadcast" parent="AndroidManifest">
        <attr name="name" />
        <attr name="permission" />
    </declare-styleable>

    <!-- Private tag to declare the original package name that this package is
+2 −1
Original line number Diff line number Diff line
@@ -16962,7 +16962,8 @@ public final class ActivityManagerService extends ActivityManagerNative
        } else if (callerApp == null || !callerApp.persistent) {
            try {
                if (AppGlobals.getPackageManager().isProtectedBroadcast(
                        intent.getAction())) {
                        intent.getAction()) && !AppGlobals.getPackageManager()
                        .isProtectedBroadcastAllowed(intent.getAction(), callingUid)) {
                    String msg = "Permission Denial: not allowed to send broadcast "
                            + intent.getAction() + " from pid="
                            + callingPid + ", uid=" + callingUid;
+16 −3
Original line number Diff line number Diff line
@@ -617,7 +617,7 @@ public class PackageManagerService extends IPackageManager.Stub {
    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
    // Broadcast actions that are only available to the system.
    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
    final ArrayMap<String, String> mProtectedBroadcasts = new ArrayMap<>();
    /** List of packages waiting for verification. */
    final SparseArray<PackageVerificationState> mPendingVerification
@@ -4041,7 +4041,19 @@ public class PackageManagerService extends IPackageManager.Stub {
    @Override
    public boolean isProtectedBroadcast(String actionName) {
        synchronized (mPackages) {
            return mProtectedBroadcasts.contains(actionName);
            return mProtectedBroadcasts.containsKey(actionName);
        }
    }
    @Override
    public boolean isProtectedBroadcastAllowed(String actionName, int callingUid) {
        synchronized (mPackages) {
            if (mProtectedBroadcasts.containsKey(actionName)) {
               final int result = checkUidPermission(mProtectedBroadcasts.get(actionName),
                        callingUid);
                return result == PackageManager.PERMISSION_GRANTED;
            }
            return false;
        }
    }
@@ -7841,7 +7853,8 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (pkg.protectedBroadcasts != null) {
                N = pkg.protectedBroadcasts.size();
                for (i=0; i<N; i++) {
                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
                    mProtectedBroadcasts.put(pkg.protectedBroadcasts.keyAt(i),
                            pkg.protectedBroadcasts.valueAt(i));
                }
            }