From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= <matiashe@google.com>
Date: Thu, 15 Jun 2023 18:31:34 +0200
Subject: [PATCH] Forbid granting access to NLSes with too-long component names

This makes the limitation, which was previously only checked on the Settings UI, enforced everywhere.

Fixes: 260570119
Fixes: 286043036
Test: atest + manually
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:dc71156a29427c8b228129f5b1368392f297835b)
Merged-In: I4c25d80978cb37a8fa1531f5045259d25ac64692
Change-Id: I4c25d80978cb37a8fa1531f5045259d25ac64692
---
 .../java/android/app/NotificationManager.java |  6 ++++
 .../NotificationManagerService.java           |  5 ++++
 .../android/server/vr/VrManagerService.java   |  6 +++-
 .../NotificationManagerServiceTest.java       | 28 +++++++++++++++++++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index f6dc5d15f385..32f40a805502 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -308,6 +308,12 @@ public class NotificationManager {
      */
     public static final int IMPORTANCE_MAX = 5;
 
+    /**
+     * Maximum length of the component name of a registered NotificationListenerService.
+     * @hide
+     */
+    public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;
+
     private static INotificationManager sService;
 
     /** @hide */
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0ac51524a648..ca0ec012fb60 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3540,6 +3540,11 @@ public class NotificationManagerService extends SystemService {
                 boolean granted) throws RemoteException {
             Preconditions.checkNotNull(listener);
             checkCallerIsSystemOrShell();
+            if (granted && listener.flattenToString().length()
+                    > NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
+                throw new IllegalArgumentException(
+                        "Component name too long: " + listener.flattenToString());
+            }
             final long identity = Binder.clearCallingIdentity();
             try {
                 if (mAllowedManagedServicePackages.test(listener.getPackageName())) {
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index faa197e984cf..87f66de5c704 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -1055,7 +1055,11 @@ public class VrManagerService extends SystemService
 
         for (ComponentName c : possibleServices) {
             if (Objects.equals(c.getPackageName(), pkg)) {
-                nm.setNotificationListenerAccessGrantedForUser(c, userId, true);
+                try {
+                    nm.setNotificationListenerAccessGrantedForUser(c, userId, true);
+                } catch (Exception e) {
+                    Slog.w(TAG, "Could not grant NLS access to package " + pkg, e);
+                }
             }
         }
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 9592e1905b54..e073e6767da6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -2021,6 +2021,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                 any(), anyInt(), anyBoolean(), anyBoolean());
     }
 
+    @Test
+    public void testSetListenerAccessForUser_grantWithNameTooLong_throws() throws Exception {
+        UserHandle user = UserHandle.of(mContext.getUserId() + 10);
+        ComponentName c = new ComponentName("com.example.package",
+                com.google.common.base.Strings.repeat("Blah", 150));
+
+        try {
+            mBinderService.setNotificationListenerAccessGrantedForUser(c, user.getIdentifier(),
+                    /* enabled= */ true);
+            fail("Should've thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Good!
+        }
+    }
+
+    @Test
+    public void testSetListenerAccessForUser_revokeWithNameTooLong_okay() throws Exception {
+        UserHandle user = UserHandle.of(mContext.getUserId() + 10);
+        ComponentName c = new ComponentName("com.example.package",
+                com.google.common.base.Strings.repeat("Blah", 150));
+
+        mBinderService.setNotificationListenerAccessGrantedForUser(
+                c, user.getIdentifier(), /* enabled= */ false);
+
+        verify(mListeners).setPackageOrComponentEnabled(
+                c.flattenToString(), user.getIdentifier(), true, /* enabled= */ false);
+    }
+
     @Test
     public void testSetAssistantAccessForUser() throws Exception {
         UserHandle user = UserHandle.of(10);
