Reset per-pkg app-ops for runtime permissions

... on every boot.

These should never have been set, but we allow settings them via the
shell.

- Also previously a bug set per-pkg app-ops.
- Also set the app-op correctly when a fg/bg permission looses it's bg
permission.

Test: Set per-pkg app-opp. Rebooted and saw log message.
      atest --test-mapping frameworks/base/services/core/java/com/android/server/pm/permission/:presubmit
Change-Id: If3b56fc08783ea99b4dba70c5fa275b94411ce94
Fixes: 123177944
This commit is contained in:
Philip P. Moltmann
2019-01-25 16:42:36 -08:00
parent 3abecb462b
commit dde0785228
4 changed files with 123 additions and 3 deletions

View File

@@ -78,7 +78,7 @@ public abstract class AppOpsManagerInternal {
/**
* Sets the app-ops mode for a certain app-op and uid.
*
* <p>Similar as {@link AppOpsManager#setMode} but does not require the package manager to be
* <p>Similar as {@link AppOpsManager#setUidMode} but does not require the package manager to be
* working. Hence this can be used very early during boot.
*
* <p>Only for internal callers. Does <u>not</u> verify that package name belongs to uid.
@@ -88,4 +88,12 @@ public abstract class AppOpsManagerInternal {
* @param mode The new mode to set.
*/
public abstract void setUidMode(int code, int uid, int mode);
/**
* Set all {@link #setMode (package) modes} for this uid to the default value.
*
* @param code The app-op
* @param uid The uid
*/
public abstract void setAllPkgModesToDefault(int code, int uid);
}

View File

@@ -16,8 +16,8 @@
package com.android.server.appop;
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
import static android.app.AppOpsManager.UID_STATE_CACHED;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
@@ -94,9 +94,9 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParser;
@@ -1282,6 +1282,46 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
/**
* Set all {@link #setMode (package) modes} for this uid to the default value.
*
* @param code The app-op
* @param uid The uid
*/
private void setAllPkgModesToDefault(int code, int uid) {
synchronized (this) {
UidState uidState = getUidStateLocked(uid, false);
if (uidState == null) {
return;
}
ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
if (pkgOps == null) {
return;
}
int numPkgs = pkgOps.size();
for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
Ops ops = pkgOps.valueAt(pkgNum);
Op op = ops.get(code);
if (op == null) {
continue;
}
int defaultMode = AppOpsManager.opToDefaultMode(code);
if (op.mode != defaultMode) {
Slog.w(TAG, "resetting app-op mode for " + AppOpsManager.opToName(code) + " of "
+ pkgOps.keyAt(pkgNum));
op.mode = defaultMode;
scheduleWriteLocked();
}
}
}
}
@Override
public void setMode(int code, int uid, String packageName, int mode) {
setMode(code, uid, packageName, mode, true, false);
@@ -4387,5 +4427,10 @@ public class AppOpsService extends IAppOpsService.Stub {
public void setUidMode(int code, int uid, int mode) {
AppOpsService.this.setUidMode(code, uid, mode);
}
@Override
public void setAllPkgModesToDefault(int code, int uid) {
AppOpsService.this.setAllPkgModesToDefault(code, uid);
}
}
}

View File

@@ -1049,6 +1049,8 @@ public class PermissionManagerService {
updatedUserIds);
updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
permissionsState, pkg, updatedUserIds);
setAppOpsLocked(permissionsState, pkg);
}
// Persist the runtime permissions state for users with changes. If permissions
@@ -1387,6 +1389,60 @@ public class PermissionManagerService {
return updatedUserIds;
}
/**
* Fix app-op modes for runtime permissions.
*
* @param permsState The state of the permissions of the package
* @param pkg The package information
*/
private void setAppOpsLocked(@NonNull PermissionsState permsState,
@NonNull PackageParser.Package pkg) {
for (int userId : UserManagerService.getInstance().getUserIds()) {
int numPerms = pkg.requestedPermissions.size();
for (int i = 0; i < numPerms; i++) {
String permission = pkg.requestedPermissions.get(i);
int op = permissionToOpCode(permission);
if (op == OP_NONE) {
continue;
}
// Runtime permissions are per uid, not per package, hence per package app-op
// modes should never have been set. It is possible to set them via the shell
// though. Revert such settings during boot to get the device back into a good
// state.
LocalServices.getService(AppOpsManagerInternal.class).setAllPkgModesToDefault(
op, getUid(userId, getAppId(pkg.applicationInfo.uid)));
// For pre-M apps the runtime permission do not store the state
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
continue;
}
PermissionState state = permsState.getRuntimePermissionState(permission, userId);
if (state == null) {
continue;
}
// Adjust app-op mods for foreground/background permissions. If an package used to
// have both fg and bg permission granted and it lost the bg permission during an
// upgrade the app-op mode should get downgraded to foreground.
if (state.isGranted()) {
BasePermission bp = mSettings.getPermission(permission);
if (bp != null && bp.perm != null && bp.perm.info != null
&& bp.perm.info.backgroundPermission != null) {
PermissionState bgState = permsState.getRuntimePermissionState(
bp.perm.info.backgroundPermission, userId);
setAppOpMode(permission, pkg, userId, bgState != null && bgState.isGranted()
? MODE_ALLOWED : MODE_FOREGROUND);
}
}
}
}
}
private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
boolean allowed = false;
final int NP = PackageParser.NEW_PERMISSIONS.length;

View File

@@ -7,6 +7,17 @@
"include-filter": "com.google.android.permission.gts.DefaultPermissionGrantPolicyTest"
}
]
},
{
"name": "CtsPermissionTestCases",
"options": [
{
"include-filter": "android.permission.cts.BackgroundPermissionsTest"
},
{
"include-filter": "android.permission.cts.SplitPermissionTest"
}
]
}
]
}