Skip to content

Commit

Permalink
Forbid granting access to NLSes with too-long component names
Browse files Browse the repository at this point in the history
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:6fcdbd0c6efc67b014b8e1b43c5ec233f912ee8b)
Merged-In: I4c25d80978cb37a8fa1531f5045259d25ac64692
Change-Id: I4c25d80978cb37a8fa1531f5045259d25ac64692
  • Loading branch information
Matías Hernández authored and thestinger committed Sep 6, 2023
1 parent b55563b commit a80971a
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 3 deletions.
6 changes: 6 additions & 0 deletions core/java/android/app/NotificationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ public class NotificationManager {
*/
public static final int BUBBLE_PREFERENCE_SELECTED = 2;

/**
* Maximum length of the component name of a registered NotificationListenerService.
* @hide
*/
public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;

@UnsupportedAppUsage
private static INotificationManager sService;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,9 @@ public String getPackageName() {
return mHelper != null ? mHelper.packageName : null;
}

public void updateState(@NonNull String packageName, int uid, boolean isEnabled) {
/** Updates enabled state based on associated package. */
public void updateState(
@NonNull String packageName, int uid, boolean isEnableAllowed, boolean isEnabled) {
mHelper.updatePackageDetails(packageName, uid);
if (mAppOpsManager == null) {
mAppOpsManager = getContext().getSystemService(AppOpsManager.class);
Expand All @@ -254,7 +256,9 @@ public void updateState(@NonNull String packageName, int uid, boolean isEnabled)
final boolean ecmEnabled = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_enhancedConfirmationModeEnabled);
final boolean appOpsAllowed = !ecmEnabled || mode == AppOpsManager.MODE_ALLOWED;
if (isEnabled) {
if (!isEnableAllowed && !isEnabled) {
setEnabled(false);
} else if (isEnabled) {
setEnabled(true);
} else if (appOpsAllowed && isDisabledByAppOps()) {
setEnabled(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5529,6 +5529,11 @@ public void setNotificationListenerAccessGrantedForUser(ComponentName listener,
boolean granted, boolean userSet) {
Objects.requireNonNull(listener);
checkNotificationListenerAccess();
if (granted && listener.flattenToString().length()
> NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
throw new IllegalArgumentException(
"Component name too long: " + listener.flattenToString());
}
if (!userSet && isNotificationListenerAccessUserSet(listener)) {
// Don't override user's choice
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,11 @@ private void grantNotificationListenerAccess(String pkg, int userId) {

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);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyLong;
Expand Down Expand Up @@ -3846,6 +3847,30 @@ public void testSetListenerAccessForUser() throws Exception {
any(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean());
}

@Test
public void testSetListenerAccessForUser_grantWithNameTooLong_throws() {
UserHandle user = UserHandle.of(mContext.getUserId() + 10);
ComponentName c = new ComponentName("com.example.package",
com.google.common.base.Strings.repeat("Blah", 150));

assertThrows(IllegalArgumentException.class,
() -> mBinderService.setNotificationListenerAccessGrantedForUser(
c, user.getIdentifier(), /* enabled= */ true, true));
}

@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, true);

verify(mListeners).setPackageOrComponentEnabled(
c.flattenToString(), user.getIdentifier(), true, /* enabled= */ false, true);
}

@Test
public void testSetAssistantAccessForUser() throws Exception {
UserInfo ui = new UserInfo();
Expand Down

0 comments on commit a80971a

Please sign in to comment.