Check for fixed permissions when restoring notification permissions

Ensure that REVIEW_REQUIRED is not set on system or policy fixed
permissions, or on GRANTED_BY_DEFAULT and GRANTED_BY_ROLE permissions.
Also removes Droidfooder-only state

Fixes: 218593876
Test: PermissionHelperTest
Change-Id: Ia830aa0fe4e60292d5808f29f126392e52883596
This commit is contained in:
Nate Myren
2022-02-10 10:34:52 -08:00
parent f501ad2d0a
commit 2d535bf2af
3 changed files with 84 additions and 32 deletions

View File

@@ -178,6 +178,12 @@ public final class PermissionHelper {
boolean userSet, boolean reviewRequired) {
assertFlag();
final long callingId = Binder.clearCallingIdentity();
// Do not change fixed permissions, and do not change non-user set permissions that are
// granted by default, or granted by role.
if (isPermissionFixed(packageName, userId)
|| (isPermissionGrantedByDefaultOrRole(packageName, userId) && !userSet)) {
return;
}
try {
if (grant && !reviewRequired) {
mPermManager.grantRuntimePermission(packageName, NOTIFICATION_PERMISSION, userId);
@@ -252,6 +258,24 @@ public final class PermissionHelper {
}
}
boolean isPermissionGrantedByDefaultOrRole(String packageName, @UserIdInt int userId) {
assertFlag();
final long callingId = Binder.clearCallingIdentity();
try {
try {
int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
userId);
return (flags & (PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT
| PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE)) != 0;
} catch (RemoteException e) {
Slog.e(TAG, "Could not reach system server", e);
}
return false;
} finally {
Binder.restoreCallingIdentity(callingId);
}
}
private void assertFlag() {
if (!mMigrationEnabled) {
throw new IllegalStateException("Method called without checking flag value");

View File

@@ -3170,44 +3170,12 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms, newPerm, ps,
pkg);
}
} else if (NOTIFICATION_PERMISSIONS.contains(newPerm)) {
//&& (origPs.getPermissionState(newPerm) == null) {
// TODO(b/205888750): add back line about origPs once all TODO sections below are
// propagated through droidfood
Permission bp = mRegistry.getPermission(newPerm);
if (bp == null) {
throw new IllegalStateException("Unknown new permission " + newPerm);
}
if (!isUserSetOrPregrantedOrFixed(ps.getPermissionFlags(newPerm))) {
updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
int setFlag = ps.isPermissionGranted(newPerm)
? 0 : FLAG_PERMISSION_REVIEW_REQUIRED;
ps.updatePermissionFlags(bp, FLAG_PERMISSION_REVIEW_REQUIRED, setFlag);
// TODO(b/205888750): remove if/else block once propagated through droidfood
if (ps.isPermissionGranted(newPerm)
&& pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
ps.revokePermission(bp);
} else if (!ps.isPermissionGranted(newPerm)
&& pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
ps.grantPermission(bp);
}
} else {
// TODO(b/205888750): remove once propagated through droidfood
ps.updatePermissionFlags(bp, FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
| FLAG_PERMISSION_REVIEW_REQUIRED, 0);
}
}
}
return updatedUserIds;
}
private boolean isUserSetOrPregrantedOrFixed(int flags) {
return (flags & (FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED
| FLAG_PERMISSION_POLICY_FIXED | FLAG_PERMISSION_SYSTEM_FIXED
| FLAG_PERMISSION_GRANTED_BY_DEFAULT | FLAG_PERMISSION_GRANTED_BY_ROLE)) != 0;
}
@NonNull
@Override
public List<SplitPermissionInfoParcelable> getSplitPermissions() {

View File

@@ -15,6 +15,7 @@
*/
package com.android.server.notification;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
@@ -251,6 +252,39 @@ public class PermissionHelperTest extends UiServiceTestCase {
FLAG_PERMISSION_REVIEW_REQUIRED, FLAG_PERMISSION_REVIEW_REQUIRED, true, 10);
}
@Test
public void testSetNotificationPermission_pkgPerm_notUserSet_grantedByDefaultPermNotSet()
throws Exception {
when(mPermManager.getPermissionFlags(anyString(),
eq(Manifest.permission.POST_NOTIFICATIONS),
anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
"pkg", 10, true, false);
mPermissionHelper.setNotificationPermission(pkgPerm);
verify(mPermManager, never()).revokeRuntimePermission(
anyString(), anyString(), anyInt(), anyString());
verify(mPermManager, never()).updatePermissionFlags(
anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
}
@Test
public void testSetNotificationPermission_pkgPerm_userSet_grantedByDefaultPermSet()
throws Exception {
when(mPermManager.getPermissionFlags(anyString(),
eq(Manifest.permission.POST_NOTIFICATIONS),
anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
"pkg", 10, true, true);
mPermissionHelper.setNotificationPermission(pkgPerm);
verify(mPermManager).grantRuntimePermission(
"pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_REVIEW_REQUIRED,
FLAG_PERMISSION_USER_SET, true, 10);
}
@Test
public void testSetNotificationPermission_revokeUserSet() throws Exception {
mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
@@ -282,6 +316,32 @@ public class PermissionHelperTest extends UiServiceTestCase {
anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
}
@Test
public void testSetNotificationPermission_SystemFixedPermNotSet() throws Exception {
when(mPermManager.getPermissionFlags(anyString(),
eq(Manifest.permission.POST_NOTIFICATIONS),
anyInt())).thenReturn(FLAG_PERMISSION_SYSTEM_FIXED);
mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
verify(mPermManager, never()).revokeRuntimePermission(
anyString(), anyString(), anyInt(), anyString());
verify(mPermManager, never()).updatePermissionFlags(
anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
}
@Test
public void testSetNotificationPermission_PolicyFixedPermNotSet() throws Exception {
when(mPermManager.getPermissionFlags(anyString(),
eq(Manifest.permission.POST_NOTIFICATIONS),
anyInt())).thenReturn(FLAG_PERMISSION_POLICY_FIXED);
mPermissionHelper.setNotificationPermission("pkg", 10, false, true);
verify(mPermManager, never()).revokeRuntimePermission(
anyString(), anyString(), anyInt(), anyString());
verify(mPermManager, never()).updatePermissionFlags(
anyString(), anyString(), anyInt(), anyInt(), anyBoolean(), anyInt());
}
@Test
public void testIsPermissionFixed() throws Exception {
when(mPermManager.getPermissionFlags(anyString(),