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

Commit ce23bf32 authored by Michael Groover's avatar Michael Groover Committed by Android (Google) Code Review
Browse files

Merge "Use StatsLog to log packages denied access to device identifiers"

parents 48cf3824 4a0ca941
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ message Atom {
        ProcessStartTime process_start_time = 169;
        PermissionGrantRequestResultReported permission_grant_request_result_reported = 170;
        BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
        DeviceIdentifierAccessDenied device_identifier_access_denied = 172;
    }

    // Pulled events will start at field 10000.
@@ -5447,3 +5448,22 @@ message DangerousPermissionState {
    optional bool is_granted = 4;
}

/**
 * Logs when a package is denied access to a device identifier based on the new access requirements.
 *
 * Logged from:
 *     frameworks/base/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
 */
message DeviceIdentifierAccessDenied {
    // The name of the package denied access to the requested device identifier.
    optional string package_name = 1;

    // The name of the device identifier method the package attempted to invoke.
    optional string method_name = 2;

    // True if the package is preinstalled.
    optional bool is_preinstalled = 3;

    // True if the package is privileged.
    optional bool is_priv_app = 4;
}
+47 −18
Original line number Diff line number Diff line
@@ -35,9 +35,14 @@ import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.StatsLog;

import com.android.internal.annotations.VisibleForTesting;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;

/** Utility class for Telephony permission enforcement. */
@@ -49,6 +54,14 @@ public final class TelephonyPermissions {
    private static final Supplier<ITelephony> TELEPHONY_SUPPLIER = () ->
            ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));

    // Contains a mapping of packages that did not meet the new requirements to access device
    // identifiers and the methods they were attempting to invoke; used to prevent duplicate
    // reporting of packages / methods.
    private static final Map<String, Set<String>> sReportedDeviceIDPackages;
    static {
        sReportedDeviceIDPackages = new HashMap<>();
    }

    private TelephonyPermissions() {}

    /**
@@ -285,47 +298,63 @@ public final class TelephonyPermissions {
     */
    private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid,
            int uid, String callingPackage, String message) {
        // Check if the application is a 3P app; if so then a separate setting is required to relax
        // the check to begin flagging problems with 3P apps early.
        // Check if the application is not preinstalled; if not then a separate setting is required
        // to relax the check to begin flagging problems with non-preinstalled apps early.
        boolean relax3PDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED, 0) == 1;
        boolean is3PApp = true;
        boolean isPreinstalled = false;
        // Also check if the application is a preloaded non-privileged app; if so there is a
        // separate setting to relax the check for these apps to ensure users can relax the check
        // for 3P or non-priv apps as needed while continuing to test the other.
        // for non-preinstalled or non-priv apps as needed while continuing to test the other.
        boolean relaxNonPrivDeviceIdentifierCheck = Settings.Global.getInt(
                context.getContentResolver(),
                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED, 0) == 1;
        boolean isNonPrivApp = false;
        boolean isPrivApp = false;
        // Similar to above support relaxing the check for privileged apps while still enforcing it
        // for non-privileged and 3P apps.
        // for non-privileged and non-preinstalled apps.
        boolean relaxPrivDeviceIdentifierCheck = Settings.Global.getInt(
                context.getContentResolver(),
                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED, 0) == 1;
        ApplicationInfo callingPackageInfo = null;
        try {
            callingPackageInfo = context.getPackageManager().getApplicationInfo(callingPackage, 0);
            if (callingPackageInfo.isSystemApp()) {
                isPreinstalled = true;
                if (callingPackageInfo.isPrivilegedApp()) {
                is3PApp = false;
            } else if (callingPackageInfo.isSystemApp()) {
                is3PApp = false;
                isNonPrivApp = true;
                    isPrivApp = true;
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            // If the application info for the calling package could not be found then assume the
            // calling app is a 3P app to detect any issues with the check
            // calling app is a non-preinstalled app to detect any issues with the check
            Log.e(LOG_TAG, "Exception caught obtaining package info for package " + callingPackage,
                    e);
        }
        // The new Q restrictions for device identifier access will be enforced for all apps with
        // settings to individually disable the new restrictions for privileged, preloaded
        // non-privileged, and 3P apps.
        // non-privileged, and non-preinstalled apps.
        if (!isIdentifierCheckDisabled() && (
                (!is3PApp && !isNonPrivApp && !relaxPrivDeviceIdentifierCheck)
                        || (is3PApp && !relax3PDeviceIdentifierCheck)
                        || (isNonPrivApp && !relaxNonPrivDeviceIdentifierCheck))) {
            Log.wtf(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
                    + ":is3PApp=" + is3PApp + ":isNonPrivApp=" + isNonPrivApp);
                (isPrivApp && !relaxPrivDeviceIdentifierCheck)
                        || (!isPreinstalled && !relax3PDeviceIdentifierCheck)
                        || (isPreinstalled && !isPrivApp && !relaxNonPrivDeviceIdentifierCheck))) {
            // The current package should only be reported in StatsLog if it has not previously been
            // reported for the currently invoked device identifier method.
            boolean packageReported = sReportedDeviceIDPackages.containsKey(callingPackage);
            if (!packageReported || !sReportedDeviceIDPackages.get(callingPackage).contains(
                    message)) {
                Set invokedMethods;
                if (!packageReported) {
                    invokedMethods = new HashSet<String>();
                    sReportedDeviceIDPackages.put(callingPackage, invokedMethods);
                } else {
                    invokedMethods = sReportedDeviceIDPackages.get(callingPackage);
                }
                invokedMethods.add(message);
                StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
                        isPreinstalled, isPrivApp);
            }
            Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
                    + ":isPreinstalled=" + isPreinstalled + ":isPrivApp=" + isPrivApp);
            // if the target SDK is pre-Q then check if the calling package would have previously
            // had access to device identifiers.
            if (callingPackageInfo != null && (