Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acbd37d2 authored by Atneya Nair's avatar Atneya Nair Committed by Android Build Coastguard Worker
Browse files

[RESTRICT AUTOMERGE] appop: Finish all when last in chain fail

When starting an op for an attribution chain, if a later attr in the
chain fails to start, we should finish the already started ops to avoid
a split in the op state in the chain.

Test: Manual with mic indicator and recording
Test: CtsMediaAudioRecordPermissionTests
Test: CtsSensorPrivacyTestCases
Bug: 325912429
Bug: 293603271
Flag: EXEMPT security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:69ff3a8c1da9d9555635fce166f6b025724c9f09)
Merged-In: I16f82c9438083f8f64f84ba710f97539960009f1
Change-Id: I16f82c9438083f8f64f84ba710f97539960009f1
parent 8b660e88
Loading
Loading
Loading
Loading
+19 −0
Original line number Original line Diff line number Diff line
@@ -1244,6 +1244,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
            final boolean hasChain = attributionChainId != ATTRIBUTION_CHAIN_ID_NONE;
            final boolean hasChain = attributionChainId != ATTRIBUTION_CHAIN_ID_NONE;
            AttributionSource current = attributionSource;
            AttributionSource current = attributionSource;
            AttributionSource next = null;
            AttributionSource next = null;
            AttributionSource prev = null;
            // We consider the chain trusted if the start node has UPDATE_APP_OPS_STATS, and
            // 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.
            // every attributionSource in the chain is registered with the system.
            final boolean isChainStartTrusted = !hasChain || checkPermission(context,
            final boolean isChainStartTrusted = !hasChain || checkPermission(context,
@@ -1310,6 +1311,22 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                        selfAccess, singleReceiverFromDatasource, attributedOp,
                        selfAccess, singleReceiverFromDatasource, attributedOp,
                        proxyAttributionFlags, proxiedAttributionFlags, attributionChainId);
                        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) {
                switch (opMode) {
                    case AppOpsManager.MODE_ERRORED: {
                    case AppOpsManager.MODE_ERRORED: {
                        if (permission.equals(Manifest.permission.BLUETOOTH_CONNECT)) {
                        if (permission.equals(Manifest.permission.BLUETOOTH_CONNECT)) {
@@ -1335,6 +1352,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                    return PermissionChecker.PERMISSION_GRANTED;
                    return PermissionChecker.PERMISSION_GRANTED;
                }
                }


                // an attribution we have already possibly started an op for
                prev = current;
                current = next;
                current = next;
            }
            }
        }
        }