Merge "Track active AttributionSources, and finish chains on death" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a4d18e767a
@@ -172,6 +172,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
@@ -180,6 +181,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
@@ -219,6 +221,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
/** If the permission of the value is granted, so is the key */
|
/** If the permission of the value is granted, so is the key */
|
||||||
private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
|
private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
/** Map of IBinder -> Running AttributionSource */
|
||||||
|
private static final ConcurrentHashMap<IBinder, RegisteredAttribution>
|
||||||
|
sRunningAttributionSources = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
|
FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
Manifest.permission.ACCESS_FINE_LOCATION);
|
||||||
@@ -5555,8 +5561,15 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishDataDelivery(int op,
|
public void finishDataDelivery(int op,
|
||||||
|
@NonNull AttributionSourceState attributionSourceState, boolean fromDataSource) {
|
||||||
|
finishDataDelivery(mContext, op, attributionSourceState,
|
||||||
|
fromDataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void finishDataDelivery(Context context, int op,
|
||||||
@NonNull AttributionSourceState attributionSourceState, boolean fromDatasource) {
|
@NonNull AttributionSourceState attributionSourceState, boolean fromDatasource) {
|
||||||
Objects.requireNonNull(attributionSourceState);
|
Objects.requireNonNull(attributionSourceState);
|
||||||
|
AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
|
||||||
|
|
||||||
if (op == AppOpsManager.OP_NONE) {
|
if (op == AppOpsManager.OP_NONE) {
|
||||||
return;
|
return;
|
||||||
@@ -5573,7 +5586,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
// If the call is from a datasource we need to vet only the chain before it. This
|
// If the call is from a datasource we need to vet only the chain before it. This
|
||||||
// way we can avoid the datasource creating an attribution context for every call.
|
// way we can avoid the datasource creating an attribution context for every call.
|
||||||
if (!(fromDatasource && current.asState() == attributionSourceState)
|
if (!(fromDatasource && current.asState() == attributionSourceState)
|
||||||
&& next != null && !current.isTrusted(mContext)) {
|
&& next != null && !current.isTrusted(context)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5589,20 +5602,20 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
? current : next;
|
? current : next;
|
||||||
|
|
||||||
if (selfAccess) {
|
if (selfAccess) {
|
||||||
final String resolvedPackageName = resolvePackageName(mContext, accessorSource);
|
final String resolvedPackageName = resolvePackageName(context, accessorSource);
|
||||||
if (resolvedPackageName == null) {
|
if (resolvedPackageName == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAppOpsManager.finishOp(accessorSource.getToken(), op,
|
appOpsManager.finishOp(accessorSource.getToken(), op,
|
||||||
accessorSource.getUid(), resolvedPackageName,
|
accessorSource.getUid(), resolvedPackageName,
|
||||||
accessorSource.getAttributionTag());
|
accessorSource.getAttributionTag());
|
||||||
} else {
|
} else {
|
||||||
final AttributionSource resolvedAttributionSource =
|
final AttributionSource resolvedAttributionSource =
|
||||||
resolveAttributionSource(mContext, accessorSource);
|
resolveAttributionSource(context, accessorSource);
|
||||||
if (resolvedAttributionSource.getPackageName() == null) {
|
if (resolvedAttributionSource.getPackageName() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAppOpsManager.finishProxyOp(AppOpsManager.opToPublicName(op),
|
appOpsManager.finishProxyOp(AppOpsManager.opToPublicName(op),
|
||||||
resolvedAttributionSource, skipCurrentFinish);
|
resolvedAttributionSource, skipCurrentFinish);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5610,6 +5623,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegisteredAttribution registered =
|
||||||
|
sRunningAttributionSources.remove(current.getToken());
|
||||||
|
if (registered != null) {
|
||||||
|
registered.unregister();
|
||||||
|
}
|
||||||
current = next;
|
current = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5827,6 +5845,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (startDataDelivery) {
|
||||||
|
RegisteredAttribution registered = new RegisteredAttribution(context, op,
|
||||||
|
current, fromDatasource);
|
||||||
|
sRunningAttributionSources.put(current.getToken(), registered);
|
||||||
|
}
|
||||||
|
|
||||||
if (next == null || next.getNext() == null) {
|
if (next == null || next.getNext() == null) {
|
||||||
return PermissionChecker.PERMISSION_GRANTED;
|
return PermissionChecker.PERMISSION_GRANTED;
|
||||||
}
|
}
|
||||||
@@ -6153,4 +6177,43 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
|||||||
attributionSource));
|
attributionSource));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class RegisteredAttribution {
|
||||||
|
private final DeathRecipient mDeathRecipient;
|
||||||
|
private final IBinder mToken;
|
||||||
|
private final AtomicBoolean mFinished;
|
||||||
|
|
||||||
|
RegisteredAttribution(Context context, int op, AttributionSource source,
|
||||||
|
boolean fromDatasource) {
|
||||||
|
mFinished = new AtomicBoolean(false);
|
||||||
|
mDeathRecipient = () -> {
|
||||||
|
if (unregister()) {
|
||||||
|
PermissionCheckerService
|
||||||
|
.finishDataDelivery(context, op, source.asState(), fromDatasource);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mToken = source.getToken();
|
||||||
|
if (mToken != null) {
|
||||||
|
try {
|
||||||
|
mToken.linkToDeath(mDeathRecipient, 0);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
mDeathRecipient.binderDied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean unregister() {
|
||||||
|
if (mFinished.compareAndSet(false, true)) {
|
||||||
|
try {
|
||||||
|
if (mToken != null) {
|
||||||
|
mToken.unlinkToDeath(mDeathRecipient, 0);
|
||||||
|
}
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user