[DO NOT MERGE] Make GlobalScreenshot PendingIntents immutable

Mutable pending intents are a security risk. This change adds the
IMMUTABLE flag to all PendingIntents created in GlobalScreenshot.

Bug: 162738636
Test: manual
Change-Id: I1044b6aaf2b1650ff91d9a72181684d2aaea9a62
This commit is contained in:
Miranda Kephart
2020-10-06 09:17:39 -04:00
parent 89824dff8a
commit bb4bfcc575

View File

@@ -135,6 +135,7 @@ class SaveImageInBackgroundData {
imageUri = null; imageUri = null;
iconSize = 0; iconSize = 0;
} }
void clearContext() { void clearContext() {
context = null; context = null;
} }
@@ -277,7 +278,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
PendingIntent broadcastIntent = PendingIntent.getBroadcast(context, PendingIntent broadcastIntent = PendingIntent.getBroadcast(context,
mRandom.nextInt(), mRandom.nextInt(),
intent, intent,
PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
broadcastActions.add(new Notification.Action.Builder(action.getIcon(), action.title, broadcastActions.add(new Notification.Action.Builder(action.getIcon(), action.title,
broadcastIntent).setContextual(true).addExtras(extras).build()); broadcastIntent).setContextual(true).addExtras(extras).build());
} }
@@ -411,7 +412,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
PendingIntent chooserAction = PendingIntent.getBroadcast(context, 0, PendingIntent chooserAction = PendingIntent.getBroadcast(context, 0,
new Intent(context, GlobalScreenshot.TargetChosenReceiver.class), new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); PendingIntent.FLAG_CANCEL_CURRENT
| PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_IMMUTABLE);
Intent sharingChooserIntent = Intent.createChooser(sharingIntent, null, Intent sharingChooserIntent = Intent.createChooser(sharingIntent, null,
chooserAction.getIntentSender()) chooserAction.getIntentSender())
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -425,7 +428,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
.putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId) .putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId)
.putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED, .putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED,
mSmartActionsEnabled), mSmartActionsEnabled),
PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM); PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE,
UserHandle.SYSTEM);
Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder( Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
R.drawable.ic_screenshot_share, R.drawable.ic_screenshot_share,
r.getString(com.android.internal.R.string.share), shareAction); r.getString(com.android.internal.R.string.share), shareAction);
@@ -451,7 +455,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
.putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId) .putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId)
.putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED, .putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED,
mSmartActionsEnabled), mSmartActionsEnabled),
PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM); PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE,
UserHandle.SYSTEM);
Notification.Action.Builder editActionBuilder = new Notification.Action.Builder( Notification.Action.Builder editActionBuilder = new Notification.Action.Builder(
R.drawable.ic_screenshot_edit, R.drawable.ic_screenshot_edit,
r.getString(com.android.internal.R.string.screenshot_edit), editAction); r.getString(com.android.internal.R.string.screenshot_edit), editAction);
@@ -464,7 +469,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
.putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId) .putExtra(GlobalScreenshot.EXTRA_ID, mScreenshotId)
.putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED, .putExtra(GlobalScreenshot.EXTRA_SMART_ACTIONS_ENABLED,
mSmartActionsEnabled), mSmartActionsEnabled),
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT); PendingIntent.FLAG_CANCEL_CURRENT
| PendingIntent.FLAG_ONE_SHOT
| PendingIntent.FLAG_IMMUTABLE);
Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder( Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder(
R.drawable.ic_screenshot_delete, R.drawable.ic_screenshot_delete,
r.getString(com.android.internal.R.string.delete), deleteAction); r.getString(com.android.internal.R.string.delete), deleteAction);
@@ -507,7 +514,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
mPublicNotificationBuilder mPublicNotificationBuilder
.setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentTitle(r.getString(R.string.screenshot_saved_title))
.setContentText(r.getString(R.string.screenshot_saved_text)) .setContentText(r.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent,
PendingIntent.FLAG_IMMUTABLE))
.setWhen(now) .setWhen(now)
.setAutoCancel(true) .setAutoCancel(true)
.setColor(context.getColor( .setColor(context.getColor(
@@ -515,7 +523,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
mNotificationBuilder mNotificationBuilder
.setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentTitle(r.getString(R.string.screenshot_saved_title))
.setContentText(r.getString(R.string.screenshot_saved_text)) .setContentText(r.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent,
PendingIntent.FLAG_IMMUTABLE))
.setWhen(now) .setWhen(now)
.setAutoCancel(true) .setAutoCancel(true)
.setColor(context.getColor( .setColor(context.getColor(
@@ -633,7 +642,8 @@ class GlobalScreenshot {
// Inflate the screenshot layout // Inflate the screenshot layout
mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null); mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background); mBackgroundView = (ImageView) mScreenshotLayout.findViewById(
R.id.global_screenshot_background);
mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot); mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot);
mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash); mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
mScreenshotSelectorView = (ScreenshotSelectorView) mScreenshotLayout.findViewById( mScreenshotSelectorView = (ScreenshotSelectorView) mScreenshotLayout.findViewById(
@@ -857,6 +867,7 @@ class GlobalScreenshot {
} }
}); });
} }
private ValueAnimator createScreenshotDropInAnimation() { private ValueAnimator createScreenshotDropInAnimation() {
final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION) final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)
/ SCREENSHOT_DROP_IN_DURATION); / SCREENSHOT_DROP_IN_DURATION);
@@ -906,6 +917,7 @@ class GlobalScreenshot {
mScreenshotFlash.setAlpha(0f); mScreenshotFlash.setAlpha(0f);
mScreenshotFlash.setVisibility(View.VISIBLE); mScreenshotFlash.setVisibility(View.VISIBLE);
} }
@Override @Override
public void onAnimationEnd(android.animation.Animator animation) { public void onAnimationEnd(android.animation.Animator animation) {
mScreenshotFlash.setVisibility(View.GONE); mScreenshotFlash.setVisibility(View.GONE);
@@ -927,6 +939,7 @@ class GlobalScreenshot {
}); });
return anim; return anim;
} }
private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible, private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible,
boolean navBarVisible) { boolean navBarVisible) {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
@@ -948,7 +961,8 @@ class GlobalScreenshot {
public void onAnimationUpdate(ValueAnimator animation) { public void onAnimationUpdate(ValueAnimator animation) {
float t = (Float) animation.getAnimatedValue(); float t = (Float) animation.getAnimatedValue();
float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale) float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
- t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE); - t * (SCREENSHOT_DROP_IN_MIN_SCALE
- SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);
mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA); mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
mScreenshotView.setAlpha(1f - t); mScreenshotView.setAlpha(1f - t);
mScreenshotView.setScaleX(scaleT); mScreenshotView.setScaleX(scaleT);
@@ -975,8 +989,10 @@ class GlobalScreenshot {
float halfScreenHeight = (h - 2f * mBgPadding) / 2f; float halfScreenHeight = (h - 2f * mBgPadding) / 2f;
final float offsetPct = SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET; final float offsetPct = SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET;
final PointF finalPos = new PointF( final PointF finalPos = new PointF(
-halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth, -halfScreenWidth
-halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight); + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth,
-halfScreenHeight
+ (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight);
// Animate the screenshot to the status bar // Animate the screenshot to the status bar
anim.setDuration(SCREENSHOT_DROP_OUT_DURATION); anim.setDuration(SCREENSHOT_DROP_OUT_DURATION);
@@ -1021,7 +1037,7 @@ class GlobalScreenshot {
DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
if (intent != null) { if (intent != null) {
final PendingIntent pendingIntent = PendingIntent.getActivityAsUser( final PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
context, 0, intent, 0, null, UserHandle.CURRENT); context, 0, intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT);
b.setContentIntent(pendingIntent); b.setContentIntent(pendingIntent);
} }