From 6c1fbf2ed96fc62e5e1ece28e8cd8a973174fa84 Mon Sep 17 00:00:00 2001 From: Rubin Xu Date: Fri, 30 Aug 2019 15:51:53 +0100 Subject: Allow privileged apps to query contact provider across user Callers with INTERACT_ACROSS_USERS or INTERACT_ACROSS_USERS_FULL should be able to query contact provider for other users. Bug: 138781676 Test: CTS verifier - Notification Attention Management Tests Test: atest ContactsProviderTests Change-Id: I5d91c9efa1134daf88cef422f979552105a4f6c4 (cherry picked from commit 24e09f9553f0f63be1e44df770b97a59fcd7f020) --- .../providers/contacts/ContactsProvider2.java | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java index 02c8bf00..c43cc1ed 100644 --- a/src/com/android/providers/contacts/ContactsProvider2.java +++ b/src/com/android/providers/contacts/ContactsProvider2.java @@ -16,6 +16,10 @@ package com.android.providers.contacts; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.Manifest.permission.INTERACT_ACROSS_USERS; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.OnAccountsUpdateListener; @@ -214,7 +218,6 @@ public class ContactsProvider2 extends AbstractContactsProvider private static final String READ_PERMISSION = "android.permission.READ_CONTACTS"; private static final String WRITE_PERMISSION = "android.permission.WRITE_CONTACTS"; - private static final String INTERACT_ACROSS_USERS = "android.permission.INTERACT_ACROSS_USERS"; /* package */ static final String PHONEBOOK_COLLATOR_NAME = "PHONEBOOK"; @@ -5454,9 +5457,13 @@ public class ContactsProvider2 extends AbstractContactsProvider return null; } - // Check enterprise policy if caller does not come from same profile - if (!(isCallerFromSameUser() || mEnterprisePolicyGuard.isCrossProfileAllowed(uri))) { - return createEmptyCursor(uri, projection); + // If caller does not come from same profile, Check if it's privileged or allowed by + // enterprise policy + if (!isCallerFromSameUser()) { + if (!callerHoldsInteractAcrossUserPermission() + && !mEnterprisePolicyGuard.isCrossProfileAllowed(uri)) { + return createEmptyCursor(uri, projection); + } } // Query the profile DB if appropriate. if (mapsToProfileDb(uri)) { @@ -5482,6 +5489,12 @@ public class ContactsProvider2 extends AbstractContactsProvider .getCurrentUserHandle(getContext()); } + private boolean callerHoldsInteractAcrossUserPermission() { + final Context context = getContext(); + return context.checkCallingPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED + || context.checkCallingPermission(INTERACT_ACROSS_USERS) == PERMISSION_GRANTED; + } + private Cursor queryDirectoryIfNecessary(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal) { String directory = getQueryParameter(uri, ContactsContract.DIRECTORY_PARAM_KEY); @@ -8525,10 +8538,12 @@ public class ContactsProvider2 extends AbstractContactsProvider if (!isDirectoryParamValid(uri)){ return null; } - if (!isCallerFromSameUser() /* From differnt user */ - && !mEnterprisePolicyGuard.isCrossProfileAllowed(uri) - /* Policy not allowed */){ - return null; + if (!isCallerFromSameUser()) { /* From differnt user */ + if (!callerHoldsInteractAcrossUserPermission() /* no cross user permission */ + && !mEnterprisePolicyGuard.isCrossProfileAllowed(uri) + /* Policy not allowed */){ + return null; + } } waitForAccess(mode.equals("r") ? mReadAccessLatch : mWriteAccessLatch); final AssetFileDescriptor ret; -- cgit v1.2.3