diff options
author | 2024-11-07 00:28:07 +0000 | |
---|---|---|
committer | 2024-11-07 00:28:07 +0000 | |
commit | 5fe41e4aa1d192a89c5129621269c32fec638e9f (patch) | |
tree | bd70cd1770d6ca4bc3e7a146fcc3a67a354ba5e6 | |
parent | 2e939dd63714f4b0087ec4f27697cb261118df19 (diff) | |
parent | a8eb60f82c9503214522b31679de3006c66ca577 (diff) |
Merge "Reapply "appops: Finish started proxy op when chain fails"" into main
-rw-r--r-- | services/core/java/com/android/server/pm/permission/PermissionManagerService.java | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 5fc3e332b95c..05bc69a9f1f0 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1015,7 +1015,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { permission, attributionSource, message, forDataDelivery, startDataDelivery, fromDatasource, attributedOp); // Finish any started op if some step in the attribution chain failed. - if (startDataDelivery && result != PermissionChecker.PERMISSION_GRANTED) { + if (startDataDelivery && result != PermissionChecker.PERMISSION_GRANTED + && result != PermissionChecker.PERMISSION_SOFT_DENIED) { if (attributedOp == AppOpsManager.OP_NONE) { finishDataDelivery(AppOpsManager.permissionToOpCode(permission), attributionSource.asState(), fromDatasource); @@ -1244,6 +1245,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final boolean hasChain = attributionChainId != ATTRIBUTION_CHAIN_ID_NONE; AttributionSource current = attributionSource; AttributionSource next = null; + AttributionSource prev = null; // We consider the chain trusted if the start node has UPDATE_APP_OPS_STATS, and // every attributionSource in the chain is registered with the system. final boolean isChainStartTrusted = !hasChain || checkPermission(context, @@ -1310,6 +1312,22 @@ public class PermissionManagerService extends IPermissionManager.Stub { selfAccess, singleReceiverFromDatasource, attributedOp, proxyAttributionFlags, proxiedAttributionFlags, attributionChainId); + if (startDataDelivery && opMode != AppOpsManager.MODE_ALLOWED) { + // Current failed the perm check, so if we are part-way through an attr chain, + // we need to clean up the already started proxy op higher up the chain. Note, + // proxy ops are verified two by two, which means we have to clear the 2nd next + // from the previous iteration (since it is actually curr.next which failed + // to pass the perm check). + if (prev != null) { + final var cutAttrSourceState = prev.asState(); + if (cutAttrSourceState.next.length > 0) { + cutAttrSourceState.next[0].next = new AttributionSourceState[0]; + } + finishDataDelivery(context, attributedOp, + cutAttrSourceState, fromDatasource); + } + } + switch (opMode) { case AppOpsManager.MODE_ERRORED: { if (permission.equals(Manifest.permission.BLUETOOTH_CONNECT)) { @@ -1335,6 +1353,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { return PermissionChecker.PERMISSION_GRANTED; } + // an attribution we have already possibly started an op for + prev = current; current = next; } } |