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

Commit 1ca89a99 authored by Nazanin Bakhshi's avatar Nazanin Bakhshi Committed by Gerrit Code Review
Browse files

Merge "Add device identifier permission checks to TelephonyPermissions"

parents cf5e620a 94672cea
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ message Atom {
        BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
        ProcessStartTime process_start_time = 169;
        BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
        DeviceIdentifierAccessDenied device_identifier_access_denied = 172;
        NetworkStackReported network_stack_reported = 182 [(log_from_module) = "network_stack"];
    }

@@ -3098,3 +3099,22 @@ message NetworkStackReported {
    optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES];
}

/**
 * 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;
}
 No newline at end of file
+25 −0
Original line number Diff line number Diff line
@@ -5653,6 +5653,31 @@ public class DevicePolicyManager {
        return null;
    }

    /**
     * Returns whether the specified package can read the device identifiers.
     *
     * @param packageName The package name of the app to check for device identifier access.
     * @param pid The process id of the package to be checked.
     * @param uid The uid of the package to be checked.
     * @return whether the package can read the device identifiers.
     *
     * @hide
     */
    public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) {
        throwIfParentInstance("checkDeviceIdentifierAccess");
        if (packageName == null) {
            return false;
        }
        if (mService != null) {
            try {
                return mService.checkDeviceIdentifierAccess(packageName, pid, uid);
            } catch (RemoteException re) {
                throw re.rethrowFromSystemServer();
            }
        }
        return false;
    }

    /**
     * @hide
     * @return the human readable name of the organisation associated with this DPM or {@code null}
+3 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ interface IDevicePolicyManager {
    int getDeviceOwnerUserId();

    boolean setProfileOwner(in ComponentName who, String ownerName, int userHandle);
    ComponentName getProfileOwnerAsUser(int userHandle);
    ComponentName getProfileOwner(int userHandle);
    String getProfileOwnerName(int userHandle);
    void setProfileEnabled(in ComponentName who);
@@ -153,6 +154,8 @@ interface IDevicePolicyManager {
    void clearProfileOwner(in ComponentName who);
    boolean hasUserSetupCompleted();

    boolean checkDeviceIdentifierAccess(in String packageName, int pid, int uid);

    void setDeviceOwnerLockScreenInfo(in ComponentName who, CharSequence deviceOwnerInfo);
    CharSequence getDeviceOwnerLockScreenInfo();

+5 −1
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
 */
package com.android.server.devicepolicy;

import android.annotation.UserIdInt;
import android.app.admin.IDevicePolicyManager;
import android.content.ComponentName;
import android.os.PersistableBundle;
@@ -159,4 +158,9 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
    @Override
    public void setDefaultSmsApplication(ComponentName admin, String packageName) {
    }

    @Override
    public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) {
        return false;
    }
}
+84 −15
Original line number Diff line number Diff line
@@ -60,7 +60,6 @@ import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.provider.Telephony.Carriers.DPC_URI;
import static android.provider.Telephony.Carriers.ENFORCE_KEY;
import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
@@ -69,11 +68,10 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
        .PROVISIONING_ENTRY_POINT_ADB;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker
        .STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER;
import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER;
import static com.android.server.devicepolicy.TransferOwnershipMetadataManager
        .ADMIN_TYPE_DEVICE_OWNER;
import static com.android.server.devicepolicy.TransferOwnershipMetadataManager
        .ADMIN_TYPE_PROFILE_OWNER;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -219,11 +217,11 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.Preconditions;
import com.android.internal.util.StatLogger;
import com.android.internal.util.XmlUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import com.android.internal.util.StatLogger;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
import com.android.server.devicepolicy.DevicePolicyManagerService.ActiveAdmin.TrustAgentInfo;
@@ -5188,7 +5186,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    @Override
    public void enforceCanManageCaCerts(ComponentName who, String callerPackage) {
        if (who == null) {
            if (!isCallerDelegate(callerPackage, DELEGATION_CERT_INSTALL)) {
            if (!isCallerDelegate(callerPackage, mInjector.binderGetCallingUid(),
                    DELEGATION_CERT_INSTALL)) {
                mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
            }
        } else {
@@ -5364,7 +5363,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            if (UserHandle.getUserId(callerUid) != mOwners.getDeviceOwnerUserId()) {
                throw new SecurityException("Caller not from device owner user");
            }
            if (!isCallerDelegate(callerPackage, DELEGATION_CERT_INSTALL)) {
            if (!isCallerDelegate(callerPackage, mInjector.binderGetCallingUid(),
                    DELEGATION_CERT_INSTALL)) {
                throw new SecurityException("Caller with uid " + mInjector.binderGetCallingUid() +
                        "has no permission to generate keys.");
            }
@@ -5766,15 +5766,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
     * @param scope the delegation scope to be checked.
     * @return {@code true} if the calling process is a delegate of {@code scope}.
     */
    private boolean isCallerDelegate(String callerPackage, String scope) {
    private boolean isCallerDelegate(String callerPackage, int callerUid, String scope) {
        Preconditions.checkNotNull(callerPackage, "callerPackage is null");
        if (!Arrays.asList(DELEGATIONS).contains(scope)) {
            throw new IllegalArgumentException("Unexpected delegation scope: " + scope);
        }
        // Retrieve the UID and user ID of the calling process.
        final int callingUid = mInjector.binderGetCallingUid();
        final int userId = UserHandle.getUserId(callingUid);
        final int userId = UserHandle.getUserId(callerUid);
        synchronized (getLockObject()) {
            // Retrieve user policy data.
            final DevicePolicyData policy = getUserData(userId);
@@ -5787,7 +5786,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    final int uid = mInjector.getPackageManager()
                            .getPackageUidAsUser(callerPackage, userId);
                    // Return true if the caller is actually callerPackage.
                    return uid == callingUid;
                    return uid == callerUid;
                } catch (NameNotFoundException e) {
                    // Ignore.
                }
@@ -5818,7 +5817,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                getActiveAdminForCallerLocked(who, reqPolicy);
            }
        // If no ComponentName is given ensure calling process has scope delegation.
        } else if (!isCallerDelegate(callerPackage, scope)) {
        } else if (!isCallerDelegate(callerPackage, mInjector.binderGetCallingUid(), scope)) {
            throw new SecurityException("Caller with uid " + mInjector.binderGetCallingUid()
                    + " is not a delegate of scope " + scope + ".");
        }
@@ -7782,6 +7781,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
    }
    @Override
    public ComponentName getProfileOwnerAsUser(int userHandle) {
        enforceCrossUsersPermission(userHandle);
        return getProfileOwner(userHandle);
    }
    @Override
    public ComponentName getProfileOwner(int userHandle) {
        if (!mHasFeature) {
@@ -7825,6 +7831,68 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        return getApplicationLabel(profileOwner.getPackageName(), userHandle);
    }
    @Override
    public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) {
        // If the caller is not a system app then it should only be able to check its own device
        // identifier access.
        int callingUid = mInjector.binderGetCallingUid();
        int callingPid = mInjector.binderGetCallingPid();
        if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID
                && (callingUid != uid || callingPid != pid)) {
            String message = String.format(
                    "Calling uid %d, pid %d cannot check device identifier access for package %s "
                            + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid);
            Log.w(LOG_TAG, message);
            throw new SecurityException(message);
        }
        // Verify that the specified packages matches the provided uid.
        int userId = UserHandle.getUserId(uid);
        try {
            ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId);
            // Since this call goes directly to PackageManagerService a NameNotFoundException is not
            // thrown but null data can be returned; if the appInfo for the specified package cannot
            // be found then return false to prevent crashing the app.
            if (appInfo == null) {
                Log.w(LOG_TAG,
                        String.format("appInfo could not be found for package %s", packageName));
                return false;
            } else if (uid != appInfo.uid) {
                String message = String.format("Package %s (uid=%d) does not match provided uid %d",
                        packageName, appInfo.uid, uid);
                Log.w(LOG_TAG, message);
                throw new SecurityException(message);
            }
        } catch (RemoteException e) {
            // If an exception is caught obtaining the appInfo just return false to prevent crashing
            // apps due to an internal error.
            Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e);
            return false;
        }
        // A device or profile owner must also have the READ_PHONE_STATE permission to access device
        // identifiers. If the package being checked does not have this permission then deny access.
        if (mContext.checkPermission(android.Manifest.permission.READ_PHONE_STATE, pid, uid)
                != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
        // Allow access to the device owner or delegate cert installer.
        ComponentName deviceOwner = getDeviceOwnerComponent(true);
        if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName)
                || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
            return true;
        }
        // Allow access to the profile owner for the specified user, or delegate cert installer
        ComponentName profileOwner = getProfileOwnerAsUser(userId);
        if (profileOwner != null && (profileOwner.getPackageName().equals(packageName)
                || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
            return true;
        }
        Log.w(LOG_TAG, String.format("Package %s (uid=%d, pid=%d) cannot access Device IDs",
                packageName, uid, pid));
        return false;
    }
    /**
     * Canonical name for a given package.
     */
@@ -8266,7 +8334,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    @Override
    public boolean isCallerApplicationRestrictionsManagingPackage(String callerPackage) {
        return isCallerDelegate(callerPackage, DELEGATION_APP_RESTRICTIONS);
        return isCallerDelegate(callerPackage, mInjector.binderGetCallingUid(),
                DELEGATION_APP_RESTRICTIONS);
    }
    @Override
Loading