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

Commit ba67a156 authored by Matías Hernández's avatar Matías Hernández
Browse files

Prevent accidental creation of PackagePreferences for non-existing packages

This could be caused by (indirectly) invoking PreferencesHelper.getOrCreatePackagePreferences with an INVALID_UID (e.g. as the result of NMS passing along the result of getUidForPackageAndUser for a missing package). This was never intended -- API calls can result in the creation of PackagePreferences (since the structure is lazily initialized) but only for present packages. In most cases this was prevented by other checks (e.g. canNotifyAsPackage, which fails if missing) but specifically for the "fromPrivilegedListener" methods there was no similar enforcement.

Switch the PreferencesHelper usage so that:
* setters (e.g. create/updateChannel, groups) throw if supplied an invalid uid.
* getters that should have PackagePreferences creation as a side effect (e.g. getChannel) early exit if supplied an invalid uid.
* most getters don't actually create PackagePreferences and just return default values (e.g. canShowBadge) if they don't exist yet.

(Also, unify constants for representing a missing package into Process.INVALID_UID, and fix several tests that were impropely set up).

Bug: 430250142
Test: atest NotificationManagerServiceTest PreferencesHelperTest
Flag: EXEMPT Bugfix
Change-Id: I9551d0458358db9269fbc53c454e029cddf42611
parent d61187a4
Loading
Loading
Loading
Loading
+4 −11
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.PowerWhitelistManager.REASON_NOTIFICATION_SERVICE;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.Process.INVALID_UID;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_NULL;
import static android.os.UserHandle.USER_SYSTEM;
@@ -503,7 +504,6 @@ public class NotificationManagerService extends SystemService {
     */
    private static final int NOTIFICATION_RAPID_CLEAR_THRESHOLD_MS = 5000;
    static final int INVALID_UID = -1;
    static final String ROOT_PKG = "root";
    static final String[] DEFAULT_ALLOWED_ADJUSTMENTS = new String[] {
@@ -5184,7 +5184,7 @@ public class NotificationManagerService extends SystemService {
                String conversationId) {
            if (canNotifyAsPackage(callingPkg, targetPkg, userId)
                    || isCallerSystemOrSystemUiOrShell()) {
                int targetUid = -1;
                int targetUid = INVALID_UID;
                try {
                    targetUid = mPackageManagerClient.getPackageUidAsUser(targetPkg, userId);
                } catch (NameNotFoundException e) {
@@ -5486,7 +5486,7 @@ public class NotificationManagerService extends SystemService {
                String targetPkg, @CannotBeSpecialUser @UserIdInt int userId) {
            if (canNotifyAsPackage(callingPkg, targetPkg, userId)
                || isCallingUidSystem()) {
                int targetUid = -1;
                int targetUid = INVALID_UID;
                try {
                    targetUid = mPackageManagerClient.getPackageUidAsUser(targetPkg, userId);
                } catch (NameNotFoundException e) {
@@ -7405,9 +7405,6 @@ public class NotificationManagerService extends SystemService {
                }
            }
            int uid = getUidForPackageAndUser(pkg, user);
            if (uid == INVALID_UID) {
                return null;
            }
            NotificationChannel parentChannel =
                    mPreferencesHelper.getNotificationChannel(pkg, uid, parentId, false);
            if (parentChannel == null) {
@@ -7562,14 +7559,12 @@ public class NotificationManagerService extends SystemService {
        }
        private int getUidForPackageAndUser(String pkg, UserHandle user) throws RemoteException {
            int uid = INVALID_UID;
            final long identity = Binder.clearCallingIdentity();
            try {
                uid = mPackageManager.getPackageUid(pkg, 0, user.getIdentifier());
                return mPackageManager.getPackageUid(pkg, 0, user.getIdentifier());
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
            return uid;
        }
        @Override
@@ -9224,12 +9219,10 @@ public class NotificationManagerService extends SystemService {
                if (canPostPromoted) {
                    notification.flags |= FLAG_PROMOTED_ONGOING;
                }
            }
        }
    }
    /**
     * Whether a notification can be non-dismissible.
     * A notification should be dismissible, unless it's exempted for some reason.
+97 −88

File changed.

Preview size limit exceeded, changes collapsed.

+52 −0

File changed.

Preview size limit exceeded, changes collapsed.

+76 −73

File changed.

Preview size limit exceeded, changes collapsed.