From 773862fda5d38d997f458c309856ed145cd5c893 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Wed, 7 Apr 2021 01:46:31 +0000 Subject: [PATCH] Add fallback for datasource without UPDATE_APP_OP_STATS If the datasource is not in a trusted platform component then in would not have UPDATE_APP_OPS_STATS. The problem is that an app is exposing runtime permission protected data but cannot blame others in a trusted way which would not properly show in permission usage UIs. As a fallback we are adding a proxy op handling blaming the datasource and the caller. bug: 183960997 Test: Assustant on auto projection works Change-Id: I8a341a6c46c75eff86bac7a79c4219ebb7991071 --- .../android/content/PermissionChecker.java | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java index fc963fef3eb4d..c3062fe2d575f 100644 --- a/core/java/android/content/PermissionChecker.java +++ b/core/java/android/content/PermissionChecker.java @@ -1064,11 +1064,25 @@ public final class PermissionChecker { return AppOpsManager.MODE_ERRORED; } if (selfAccess) { - return appOpsManager.startOpNoThrow(op, resolvedAttributionSource.getUid(), - resolvedAttributionSource.getPackageName(), - /*startIfModeDefault*/ false, - resolvedAttributionSource.getAttributionTag(), - message); + // If the datasource is not in a trusted platform component then in would not + // have UPDATE_APP_OPS_STATS and the call below would fail. The problem is that + // an app is exposing runtime permission protected data but cannot blame others + // in a trusted way which would not properly show in permission usage UIs. + // As a fallback we note a proxy op that blames the app and the datasource. + try { + return appOpsManager.startOpNoThrow(op, resolvedAttributionSource.getUid(), + resolvedAttributionSource.getPackageName(), + /*startIfModeDefault*/ false, + resolvedAttributionSource.getAttributionTag(), + message); + } catch (SecurityException e) { + Slog.w(LOG_TAG, "Datasource " + attributionSource + " protecting data with" + + " platform defined runtime permission " + + AppOpsManager.opToPermission(op) + " while not having " + + Manifest.permission.UPDATE_APP_OPS_STATS); + return appOpsManager.startProxyOpNoThrow(op, attributionSource, message, + skipProxyOperation); + } } else { return appOpsManager.startProxyOpNoThrow(op, resolvedAttributionSource, message, skipProxyOperation); @@ -1080,10 +1094,24 @@ public final class PermissionChecker { return AppOpsManager.MODE_ERRORED; } if (selfAccess) { - return appOpsManager.noteOpNoThrow(op, resolvedAttributionSource.getUid(), - resolvedAttributionSource.getPackageName(), - resolvedAttributionSource.getAttributionTag(), - message); + // If the datasource is not in a trusted platform component then in would not + // have UPDATE_APP_OPS_STATS and the call below would fail. The problem is that + // an app is exposing runtime permission protected data but cannot blame others + // in a trusted way which would not properly show in permission usage UIs. + // As a fallback we note a proxy op that blames the app and the datasource. + try { + return appOpsManager.noteOpNoThrow(op, resolvedAttributionSource.getUid(), + resolvedAttributionSource.getPackageName(), + resolvedAttributionSource.getAttributionTag(), + message); + } catch (SecurityException e) { + Slog.w(LOG_TAG, "Datasource " + attributionSource + " protecting data with" + + " platform defined runtime permission " + + AppOpsManager.opToPermission(op) + " while not having " + + Manifest.permission.UPDATE_APP_OPS_STATS); + return appOpsManager.noteProxyOpNoThrow(op, attributionSource, message, + skipProxyOperation); + } } else { return appOpsManager.noteProxyOpNoThrow(op, resolvedAttributionSource, message, skipProxyOperation);