diff options
| author | 2018-06-13 16:44:31 -0700 | |
|---|---|---|
| committer | 2018-10-05 16:51:13 -0700 | |
| commit | 9351985f7accbe36e3dc66818f2c5b47b5457ff6 (patch) | |
| tree | 21b0934d17d04c3edfdaa651a0b963ed6dd50159 | |
| parent | 3bc4ab482b21faf76ae1fc8201970e2eab32ad8f (diff) | |
Remove SMS access for apps other than current SMS handler
Bug: 110098858
Test: atest android.telephony.cts.SmsManagerTest#testContentProviderAccessRestrictions
Change-Id: I9da992565b04ca5fa2656801fd2cfe4b196ef9b4
12 files changed, 287 insertions, 234 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 5785e4aa3969..9dd46f75778b 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4446,6 +4446,7 @@ package android.provider { field public static final java.lang.String INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT = "install_carrier_app_notification_persistent"; field public static final java.lang.String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis"; field public static final java.lang.String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update"; + field public static final java.lang.String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled"; field public static final java.lang.String THEATER_MODE_ON = "theater_mode_on"; field public static final java.lang.String WEBVIEW_MULTIPROCESS = "webview_multiprocess"; field public static final java.lang.String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds"; diff --git a/api/test-current.txt b/api/test-current.txt index 956761615254..8bfda58d5b9b 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -84,6 +84,7 @@ package android.app { method public static java.lang.String opToPermission(int); method public static int permissionToOpCode(java.lang.String); method public void setMode(int, int, java.lang.String, int); + method public void setUidMode(java.lang.String, int, int); method public void startWatchingActive(int[], android.app.AppOpsManager.OnOpActiveChangedListener); method public void stopWatchingActive(android.app.AppOpsManager.OnOpActiveChangedListener); method public static int strOpToOp(java.lang.String); @@ -953,6 +954,7 @@ package android.provider { field public static final java.lang.String LOCATION_GLOBAL_KILL_SWITCH = "location_global_kill_switch"; field public static final java.lang.String LOW_POWER_MODE = "low_power"; field public static final java.lang.String LOW_POWER_MODE_STICKY = "low_power_sticky"; + field public static final java.lang.String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled"; field public static final java.lang.String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package"; } diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java index 12fb4a375058..1597c8c9c2b2 100644 --- a/cmds/content/src/com/android/commands/content/Content.java +++ b/cmds/content/src/com/android/commands/content/Content.java @@ -33,11 +33,7 @@ import android.os.Process; import android.os.UserHandle; import android.text.TextUtils; -import libcore.io.Streams; - import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; /** * This class is a command line utility for manipulating content. A client diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 9c47e795c81d..a05d01b5ad9a 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1256,85 +1256,85 @@ public class AppOpsManager { * This specifies the default mode for each operation. */ private static int[] sOpDefaultMode = new int[] { - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_DEFAULT, // OP_WRITE_SETTINGS - AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA - AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, // OP_TURN_ON_SCREEN - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, // OP_RUN_IN_BACKGROUND - AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ACCESSIBILITY_VOLUME - AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_DEFAULT, // OP_REQUEST_INSTALL_PACKAGES - AppOpsManager.MODE_ALLOWED, // OP_PICTURE_IN_PICTURE - AppOpsManager.MODE_DEFAULT, // OP_INSTANT_APP_START_FOREGROUND - AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS - AppOpsManager.MODE_ALLOWED, // OP_RUN_ANY_IN_BACKGROUND - AppOpsManager.MODE_ALLOWED, // OP_CHANGE_WIFI_STATE - AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES - AppOpsManager.MODE_ALLOWED, // OP_BIND_ACCESSIBILITY_SERVICE - AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER - AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS - AppOpsManager.MODE_ALLOWED, // OP_START_FOREGROUND - AppOpsManager.MODE_ALLOWED, // OP_BLUETOOTH_SCAN - AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC + AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION + AppOpsManager.MODE_ALLOWED, // FINE_LOCATION + AppOpsManager.MODE_ALLOWED, // GPS + AppOpsManager.MODE_ALLOWED, // VIBRATE + AppOpsManager.MODE_ALLOWED, // READ_CONTACTS + AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS + AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG + AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG + AppOpsManager.MODE_ALLOWED, // READ_CALENDAR + AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR + AppOpsManager.MODE_ALLOWED, // WIFI_SCAN + AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION + AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS + AppOpsManager.MODE_ALLOWED, // CALL_PHONE + AppOpsManager.MODE_DEFAULT, // READ_SMS + AppOpsManager.MODE_DEFAULT, // WRITE_SMS + AppOpsManager.MODE_DEFAULT, // RECEIVE_SMS + AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST + AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS + AppOpsManager.MODE_DEFAULT, // RECEIVE_WAP_PUSH + AppOpsManager.MODE_DEFAULT, // SEND_SMS + AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS + AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS + AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS + AppOpsManager.MODE_DEFAULT, // SYSTEM_ALERT_WINDOW + AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS + AppOpsManager.MODE_ALLOWED, // CAMERA + AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO + AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO + AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD + AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD + AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS + AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS + AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME + AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME + AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME + AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME + AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME + AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME + AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME + AppOpsManager.MODE_ALLOWED, // WAKE_LOCK + AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION + AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION + AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS + AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE + AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW + AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA + AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN + AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER + AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE + AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT + AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE + AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL + AppOpsManager.MODE_ALLOWED, // USE_SIP + AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS + AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT + AppOpsManager.MODE_ALLOWED, // BODY_SENSORS + AppOpsManager.MODE_DEFAULT, // READ_CELL_BROADCASTS + AppOpsManager.MODE_ERRORED, // MOCK_LOCATION + AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE + AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE + AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON + AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS + AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND + AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME + AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS + AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES + AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE + AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND + AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS + AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND + AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE + AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES + AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE + AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER + AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS + AppOpsManager.MODE_ALLOWED, // START_FOREGROUND + AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN + AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC }; /** @@ -1345,80 +1345,80 @@ public class AppOpsManager { * for whichever app is selected as the current SMS app). */ private static boolean[] sOpDisableReset = new boolean[] { - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true, // OP_WRITE_SMS - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, // OP_AUDIO_ACCESSIBILITY_VOLUME - false, - false, // OP_REQUEST_INSTALL_PACKAGES - false, // OP_PICTURE_IN_PICTURE - false, + false, // COARSE_LOCATION + false, // FINE_LOCATION + false, // GPS + false, // VIBRATE + false, // READ_CONTACTS + false, // WRITE_CONTACTS + false, // READ_CALL_LOG + false, // WRITE_CALL_LOG + false, // READ_CALENDAR + false, // WRITE_CALENDAR + false, // WIFI_SCAN + false, // POST_NOTIFICATION + false, // NEIGHBORING_CELLS + false, // CALL_PHONE + true, // READ_SMS + true, // WRITE_SMS + true, // RECEIVE_SMS + false, // RECEIVE_EMERGENCY_BROADCAST + false, // RECEIVE_MMS + true, // RECEIVE_WAP_PUSH + true, // SEND_SMS + false, // READ_ICC_SMS + false, // WRITE_ICC_SMS + false, // WRITE_SETTINGS + false, // SYSTEM_ALERT_WINDOW + false, // ACCESS_NOTIFICATIONS + false, // CAMERA + false, // RECORD_AUDIO + false, // PLAY_AUDIO + false, // READ_CLIPBOARD + false, // WRITE_CLIPBOARD + false, // TAKE_MEDIA_BUTTONS + false, // TAKE_AUDIO_FOCUS + false, // AUDIO_MASTER_VOLUME + false, // AUDIO_VOICE_VOLUME + false, // AUDIO_RING_VOLUME + false, // AUDIO_MEDIA_VOLUME + false, // AUDIO_ALARM_VOLUME + false, // AUDIO_NOTIFICATION_VOLUME + false, // AUDIO_BLUETOOTH_VOLUME + false, // WAKE_LOCK + false, // MONITOR_LOCATION + false, // MONITOR_HIGH_POWER_LOCATION + false, // GET_USAGE_STATS + false, // MUTE_MICROPHONE + false, // TOAST_WINDOW + false, // PROJECT_MEDIA + false, // ACTIVATE_VPN + false, // WRITE_WALLPAPER + false, // ASSIST_STRUCTURE + false, // ASSIST_SCREENSHOT + false, // READ_PHONE_STATE + false, // ADD_VOICEMAIL + false, // USE_SIP + false, // PROCESS_OUTGOING_CALLS + false, // USE_FINGERPRINT + false, // BODY_SENSORS + true, // READ_CELL_BROADCASTS + false, // MOCK_LOCATION + false, // READ_EXTERNAL_STORAGE + false, // WRITE_EXTERNAL_STORAGE + false, // TURN_SCREEN_ON + false, // GET_ACCOUNTS + false, // RUN_IN_BACKGROUND + false, // AUDIO_ACCESSIBILITY_VOLUME + false, // READ_PHONE_NUMBERS + false, // REQUEST_INSTALL_PACKAGES + false, // PICTURE_IN_PICTURE + false, // INSTANT_APP_START_FOREGROUND false, // ANSWER_PHONE_CALLS - false, // OP_RUN_ANY_IN_BACKGROUND - false, // OP_CHANGE_WIFI_STATE - false, // OP_REQUEST_DELETE_PACKAGES - false, // OP_BIND_ACCESSIBILITY_SERVICE + false, // RUN_ANY_IN_BACKGROUND + false, // CHANGE_WIFI_STATE + false, // REQUEST_DELETE_PACKAGES + false, // BIND_ACCESSIBILITY_SERVICE false, // ACCEPT_HANDOVER false, // MANAGE_IPSEC_TUNNELS false, // START_FOREGROUND @@ -1957,6 +1957,7 @@ public class AppOpsManager { * @hide */ @SystemApi + @TestApi @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) public void setUidMode(String appOp, int uid, int mode) { try { diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index a64eead04c6f..4e1a898c16a3 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -18,6 +18,7 @@ package android.content; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.app.AppOpsManager.MODE_ALLOWED; +import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.AppOpsManager.MODE_ERRORED; import static android.app.AppOpsManager.MODE_IGNORED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -569,11 +570,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { return mode; } - if (mReadOp != AppOpsManager.OP_NONE) { - return mAppOpsManager.noteProxyOp(mReadOp, callingPkg); - } - - return AppOpsManager.MODE_ALLOWED; + return noteProxyOp(callingPkg, mReadOp); } private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken) @@ -583,8 +580,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 { return mode; } - if (mWriteOp != AppOpsManager.OP_NONE) { - return mAppOpsManager.noteProxyOp(mWriteOp, callingPkg); + return noteProxyOp(callingPkg, mWriteOp); + } + + private int noteProxyOp(String callingPkg, int op) { + if (op != AppOpsManager.OP_NONE) { + int mode = mAppOpsManager.noteProxyOp(op, callingPkg); + return mode == MODE_DEFAULT ? interpretDefaultAppOpMode(op) : mode; } return AppOpsManager.MODE_ALLOWED; @@ -609,12 +611,17 @@ public abstract class ContentProvider implements ComponentCallbacks2 { return MODE_ERRORED; } - final int permOp = AppOpsManager.permissionToOpCode(permission); - if (permOp != AppOpsManager.OP_NONE) { - return mTransport.mAppOpsManager.noteProxyOp(permOp, callingPkg); - } + return mTransport.noteProxyOp(callingPkg, AppOpsManager.permissionToOpCode(permission)); + } - return MODE_ALLOWED; + /** + * Allows for custom interpretations of {@link AppOpsManager#MODE_DEFAULT} by individual + * content providers + * + * @hide + */ + protected int interpretDefaultAppOpMode(int op) { + return MODE_IGNORED; } /** {@hide} */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ad8626ce736b..38b783435590 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12314,6 +12314,18 @@ public final class Settings { "location_global_kill_switch"; /** + * If set to 1, app cannot request read sms permission unless it's the default sms handler. + * + * STOPSHIP: Remove this once we ship with the restriction enabled. + * + * @hide + */ + @SystemApi + @TestApi + public static final String SMS_ACCESS_RESTRICTION_ENABLED = + "sms_access_restriction_enabled"; + + /** * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored * and restoring to lower version of platform API will be skipped. * diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index f9f725a130ed..eb5b52c66e7b 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -739,6 +739,7 @@ message GlobalSettingsProto { optional SettingProto short_code_rule = 4 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto short_codes_update_content_url = 5; optional SettingProto short_codes_update_metadata_url = 6; + optional SettingProto access_restriction_enabled = 7 [ (android.privacy).dest = DEST_AUTOMATIC ]; } optional Sms sms = 109; diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 8f0e76bdc0c9..6dadb74c4f75 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -396,6 +396,7 @@ public class SettingsBackupTest { Settings.Global.SHOW_TEMPERATURE_WARNING, Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL, Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL, + Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS, Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT, Settings.Global.SMS_SHORT_CODE_CONFIRMATION, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index bd21b8353136..e5e15d5f3692 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1140,6 +1140,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL, GlobalSettingsProto.Sms.SHORT_CODES_UPDATE_METADATA_URL); + dumpSetting(s, p, + Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, + GlobalSettingsProto.Sms.ACCESS_RESTRICTION_ENABLED); p.end(smsToken); final long soundsToken = p.start(GlobalSettingsProto.SOUNDS); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index da870bd134bf..ee0c416966bc 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -24,6 +24,7 @@ <!-- Standard permissions granted to the shell. --> <uses-permission android:name="android.permission.SEND_SMS" /> + <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 820258022fd5..e194d1541ea7 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -384,7 +384,7 @@ public final class BasePermission { } if (!isRuntime() && !isDevelopment()) { throw new SecurityException("Permission " + name - + " is not a changeable permission type"); + + " requested by " + pkg.packageName + " is not a changeable permission type"); } } diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java index 39722c66e170..54f30157d179 100644 --- a/telephony/java/com/android/internal/telephony/SmsApplication.java +++ b/telephony/java/com/android/internal/telephony/SmsApplication.java @@ -69,6 +69,15 @@ public final class SmsApplication { private static final String SCHEME_MMSTO = "mmsto"; private static final boolean DEBUG_MULTIUSER = false; + private static final int[] DEFAULT_APP_EXCLUSIVE_APPOPS = { + AppOpsManager.OP_READ_SMS, + AppOpsManager.OP_WRITE_SMS, + AppOpsManager.OP_RECEIVE_SMS, + AppOpsManager.OP_RECEIVE_WAP_PUSH, + AppOpsManager.OP_SEND_SMS, + AppOpsManager.OP_READ_CELL_BROADCASTS + }; + private static SmsPackageMonitor sSmsPackageMonitor = null; public static class SmsApplicationData { @@ -396,6 +405,8 @@ public final class SmsApplication { final SmsApplicationData smsApplicationData = receivers.get(packageName); if (smsApplicationData != null) { if (!smsApplicationData.isComplete()) { + Log.w(LOG_TAG, "Package " + packageName + + " lacks required manifest declarations to be a default sms app"); receivers.remove(packageName); } } @@ -482,53 +493,27 @@ public final class SmsApplication { // If we found a package, make sure AppOps permissions are set up correctly if (applicationData != null) { - AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); - // We can only call checkOp if we are privileged (updateIfNeeded) or if the app we // are checking is for our current uid. Doing this check from the unprivileged current // SMS app allows us to tell the current SMS app that it is not in a good state and // needs to ask to be the current SMS app again to work properly. if (updateIfNeeded || applicationData.mUid == android.os.Process.myUid()) { // Verify that the SMS app has permissions - int mode = appOps.checkOp(AppOpsManager.OP_WRITE_SMS, applicationData.mUid, - applicationData.mPackageName); - if (mode != AppOpsManager.MODE_ALLOWED) { - Rlog.e(LOG_TAG, applicationData.mPackageName + " lost OP_WRITE_SMS: " + - (updateIfNeeded ? " (fixing)" : " (no permission to fix)")); - if (updateIfNeeded) { - appOps.setMode(AppOpsManager.OP_WRITE_SMS, applicationData.mUid, - applicationData.mPackageName, AppOpsManager.MODE_ALLOWED); - } else { - // We can not return a package if permissions are not set up correctly - applicationData = null; - } + boolean appOpsFixed = + tryFixExclusiveSmsAppops(context, applicationData, updateIfNeeded); + if (!appOpsFixed) { + // We can not return a package if permissions are not set up correctly + applicationData = null; } } // We can only verify the phone and BT app's permissions from a privileged caller - if (updateIfNeeded) { + if (applicationData != null && updateIfNeeded) { // Ensure this component is still configured as the preferred activity. Usually the // current SMS app will already be the preferred activity - but checking whether or // not this is true is just as expensive as reconfiguring the preferred activity so // we just reconfigure every time. - PackageManager packageManager = context.getPackageManager(); - configurePreferredActivity(packageManager, new ComponentName( - applicationData.mPackageName, applicationData.mSendToClass), - userId); - // Assign permission to special system apps - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - PHONE_PACKAGE_NAME); - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - BLUETOOTH_PACKAGE_NAME); - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - MMS_SERVICE_PACKAGE_NAME); - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - TELEPHONY_PROVIDER_PACKAGE_NAME); - // Give WRITE_SMS AppOps permission to UID 1001 which contains multiple - // apps, all of them should be able to write to telephony provider. - // This is to allow the proxy package permission check in telephony provider - // to pass. - assignWriteSmsPermissionToSystemUid(appOps, Process.PHONE_UID); + updateDefaultSmsApp(context, userId, applicationData); } } if (DEBUG_MULTIUSER) { @@ -537,6 +522,56 @@ public final class SmsApplication { return applicationData; } + private static void updateDefaultSmsApp(Context context, int userId, + SmsApplicationData applicationData) { + PackageManager packageManager = context.getPackageManager(); + AppOpsManager appOps = context.getSystemService(AppOpsManager.class); + + // Configure this as the preferred activity for SENDTO sms/mms intents + configurePreferredActivity(packageManager, new ComponentName( + applicationData.mPackageName, applicationData.mSendToClass), + userId); + + // Assign permission to special system apps + assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, + PHONE_PACKAGE_NAME); + assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, + BLUETOOTH_PACKAGE_NAME); + assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, + MMS_SERVICE_PACKAGE_NAME); + assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps, + TELEPHONY_PROVIDER_PACKAGE_NAME); + + // Give AppOps permission to UID 1001 which contains multiple + // apps, all of them should be able to write to telephony provider. + // This is to allow the proxy package permission check in telephony provider + // to pass. + for (int appop : DEFAULT_APP_EXCLUSIVE_APPOPS) { + appOps.setUidMode(appop, Process.PHONE_UID, AppOpsManager.MODE_ALLOWED); + } + } + + private static boolean tryFixExclusiveSmsAppops(Context context, + SmsApplicationData applicationData, boolean updateIfNeeded) { + AppOpsManager appOps = context.getSystemService(AppOpsManager.class); + for (int appOp : DEFAULT_APP_EXCLUSIVE_APPOPS) { + int mode = appOps.checkOp(appOp, applicationData.mUid, + applicationData.mPackageName); + if (mode != AppOpsManager.MODE_ALLOWED) { + Rlog.e(LOG_TAG, applicationData.mPackageName + " lost " + + AppOpsManager.modeToName(appOp) + ": " + + (updateIfNeeded ? " (fixing)" : " (no permission to fix)")); + if (updateIfNeeded) { + setExclusiveAppop(applicationData.mPackageName, appOps, appOp, + AppOpsManager.MODE_ALLOWED, applicationData.mUid); + } else { + return false; + } + } + } + return true; + } + /** * Sets the specified package as the default SMS/MMS application. The caller of this method * needs to have permission to set AppOps and write to secure settings. @@ -589,14 +624,13 @@ public final class SmsApplication { getApplicationForPackage(applications, oldPackageName) : null; SmsApplicationData applicationData = getApplicationForPackage(applications, packageName); if (applicationData != null) { - // Ignore OP_WRITE_SMS for the previously configured default SMS app. + // Ignore relevant appops for the previously configured default SMS app. AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); if (oldPackageName != null) { try { - PackageInfo info = packageManager.getPackageInfoAsUser(oldPackageName, - 0, userId); - appOps.setMode(AppOpsManager.OP_WRITE_SMS, info.applicationInfo.uid, - oldPackageName, AppOpsManager.MODE_IGNORED); + int uid = packageManager.getPackageInfoAsUser( + oldPackageName, 0, userId).applicationInfo.uid; + setExclusiveAppops(oldPackageName, appOps, uid, AppOpsManager.MODE_DEFAULT); } catch (NameNotFoundException e) { Rlog.w(LOG_TAG, "Old SMS package not found: " + oldPackageName); } @@ -607,28 +641,11 @@ public final class SmsApplication { Settings.Secure.SMS_DEFAULT_APPLICATION, applicationData.mPackageName, userId); - // Configure this as the preferred activity for SENDTO sms/mms intents - configurePreferredActivity(packageManager, new ComponentName( - applicationData.mPackageName, applicationData.mSendToClass), userId); - - // Allow OP_WRITE_SMS for the newly configured default SMS app. - appOps.setMode(AppOpsManager.OP_WRITE_SMS, applicationData.mUid, - applicationData.mPackageName, AppOpsManager.MODE_ALLOWED); - - // Assign permission to special system apps - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - PHONE_PACKAGE_NAME); - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - BLUETOOTH_PACKAGE_NAME); - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - MMS_SERVICE_PACKAGE_NAME); - assignWriteSmsPermissionToSystemApp(context, packageManager, appOps, - TELEPHONY_PROVIDER_PACKAGE_NAME); - // Give WRITE_SMS AppOps permission to UID 1001 which contains multiple - // apps, all of them should be able to write to telephony provider. - // This is to allow the proxy package permission check in telephony provider - // to pass. - assignWriteSmsPermissionToSystemUid(appOps, Process.PHONE_UID); + // Allow relevant appops for the newly configured default SMS app. + setExclusiveAppops(applicationData.mPackageName, appOps, applicationData.mUid, + AppOpsManager.MODE_ALLOWED); + + updateDefaultSmsApp(context, userId, applicationData); if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "setDefaultApplicationInternal oldAppData=" + oldAppData); @@ -685,7 +702,7 @@ public final class SmsApplication { * @param appOps The AppOps manager instance * @param packageName The package name of the system app */ - private static void assignWriteSmsPermissionToSystemApp(Context context, + private static void assignExclusiveSmsPermissionsToSystemApp(Context context, PackageManager packageManager, AppOpsManager appOps, String packageName) { // First check package signature matches the caller's package signature. // Since this class is only used internally by the system, this check makes sure @@ -701,8 +718,8 @@ public final class SmsApplication { packageName); if (mode != AppOpsManager.MODE_ALLOWED) { Rlog.w(LOG_TAG, packageName + " does not have OP_WRITE_SMS: (fixing)"); - appOps.setMode(AppOpsManager.OP_WRITE_SMS, info.applicationInfo.uid, - packageName, AppOpsManager.MODE_ALLOWED); + setExclusiveAppops(packageName, appOps, info.applicationInfo.uid, + AppOpsManager.MODE_ALLOWED); } } catch (NameNotFoundException e) { // No whitelisted system app on this device @@ -711,8 +728,19 @@ public final class SmsApplication { } - private static void assignWriteSmsPermissionToSystemUid(AppOpsManager appOps, int uid) { - appOps.setUidMode(AppOpsManager.OP_WRITE_SMS, uid, AppOpsManager.MODE_ALLOWED); + private static void setExclusiveAppops(String pkg, AppOpsManager appOpsManager, int uid, + int mode) { + for (int appop : DEFAULT_APP_EXCLUSIVE_APPOPS) { + setExclusiveAppop(pkg, appOpsManager, appop, mode, uid); + } + } + + private static void setExclusiveAppop(String pkg, AppOpsManager appOpsManager, int appop, + int mode, int uid) { + // IGNORED means user explicitly revoked permission in settings, so avoid overriding it. + if (appOpsManager.checkOpNoThrow(appop, uid, pkg) != AppOpsManager.MODE_IGNORED) { + appOpsManager.setUidMode(appop, uid, mode); + } } /** |