diff options
author | Rubin Xu <rubinxu@google.com> | 2020-05-14 15:31:16 +0100 |
---|---|---|
committer | Rubin Xu <rubinxu@google.com> | 2020-05-15 20:41:23 +0100 |
commit | aacf94557d2fa720421abd5fed248bdfac8f8c24 (patch) | |
tree | 68ca5d00f2f8dd96af5f992f20b84fdb4d5c5c34 /services/devicepolicy | |
parent | b8ad491e6d81ae96f43f57cddbd50060cdde27f5 (diff) |
Set explicit target when constructing PendingIntent
PendingIntent as part of a notification can be intercepted by
a malicious app and re-fired with crafted intent arguments.
System server should set explicit target for these intents
to avoid it being fired to other apps with system privilege.
Bug: 155183624
Test: atest FrameworksServicesTests:DevicePolicyManagerTest
Test: Set a DO/PO with TestDPC, turn on location, verify notification
works
Test: set a DO with TestDPC, request remote bugreport and verify
notifcation works
Change-Id: Ib7d0039c3d07a9d1ccf57e944303353ec9e9b66d
Diffstat (limited to 'services/devicepolicy')
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 17 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java | 15 |
2 files changed, 29 insertions, 3 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index a74706be8915..35a9f4214649 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -11933,10 +11933,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void showLocationSettingsChangedNotification(UserHandle user) { + Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // Fill the component explicitly to prevent the PendingIntent from being intercepted + // and fired with crafted target. b/155183624 + ActivityInfo targetInfo = intent.resolveActivityInfo( + mInjector.getPackageManager(user.getIdentifier()), + PackageManager.MATCH_SYSTEM_ONLY); + if (targetInfo != null) { + intent.setComponent(targetInfo.getComponentName()); + } else { + Slog.wtf(LOG_TAG, "Failed to resolve intent for location settings"); + } + PendingIntent locationSettingsIntent = mInjector.pendingIntentGetActivityAsUser(mContext, 0, - new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), PendingIntent.FLAG_UPDATE_CURRENT, - null, user); + intent, PendingIntent.FLAG_UPDATE_CURRENT, null, user); Notification notification = new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN) .setSmallIcon(R.drawable.ic_info_outline) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java index 7cfbcc87edc3..1630f271a296 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java @@ -22,9 +22,12 @@ import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; import android.os.UserHandle; import android.provider.Settings; import android.text.format.DateUtils; +import android.util.Slog; import com.android.internal.R; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; @@ -38,6 +41,7 @@ import java.lang.annotation.RetentionPolicy; */ class RemoteBugreportUtils { + private static final String TAG = "RemoteBugreportUtils"; static final int NOTIFICATION_ID = SystemMessage.NOTE_REMOTE_BUGREPORT; @Retention(RetentionPolicy.SOURCE) @@ -60,6 +64,17 @@ class RemoteBugreportUtils { Intent dialogIntent = new Intent(Settings.ACTION_SHOW_REMOTE_BUGREPORT_DIALOG); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); dialogIntent.putExtra(DevicePolicyManager.EXTRA_BUGREPORT_NOTIFICATION_TYPE, type); + + // Fill the component explicitly to prevent the PendingIntent from being intercepted + // and fired with crafted target. b/155183624 + ActivityInfo targetInfo = dialogIntent.resolveActivityInfo( + context.getPackageManager(), PackageManager.MATCH_SYSTEM_ONLY); + if (targetInfo != null) { + dialogIntent.setComponent(targetInfo.getComponentName()); + } else { + Slog.wtf(TAG, "Failed to resolve intent for remote bugreport dialog"); + } + PendingIntent pendingDialogIntent = PendingIntent.getActivityAsUser(context, type, dialogIntent, 0, null, UserHandle.CURRENT); |