From 31662cb092aa28ae039ec96a8016b0d4db452517 Mon Sep 17 00:00:00 2001 From: Nan Wu Date: Thu, 18 May 2023 19:31:45 +0000 Subject: [PATCH] Rescind PrintManager BAL privilege When PrintManager.print is called, it calls PrintMangerService that creates a PendingIntent to start the print dialog with system uid, and returns the IntentSender from that PendingIntent. Then PrintManager starts the returned IntentSender. As a result, any background app that calls this method could start bring itself to the foreground. Fix it by passing an ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED when PrintManagerService creates the PendingIntent so that its system privilege is not passed on to any client. Also, the PrintManager adds MODE_BACKGROUND_ACTIVITY_START_ALLOWED when it calls startIntentSender so that if the client app is in the foreground, the print dialog will not be blocked simply because the creator of the PI (system) is in the background. Bug: 232799700 Test: Manual test, CTS WorkflowTest and IPrintManagerParametersTest Change-Id: Iae3f583aae8570e566464f17b8ad7b2024946099 --- core/java/android/print/PrintManager.java | 7 ++++++- .../print/java/com/android/server/print/UserState.java | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index 931adb55a6867..ef274a56e1d36 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -23,6 +23,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.Activity; +import android.app.ActivityOptions; import android.app.Application.ActivityLifecycleCallbacks; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; @@ -535,7 +536,11 @@ public final class PrintManager { return null; } try { - mContext.startIntentSender(intent, null, 0, 0, 0); + ActivityOptions activityOptions = ActivityOptions.makeBasic() + .setPendingIntentBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); + mContext.startIntentSender(intent, null, 0, 0, 0, + activityOptions.toBundle()); return new PrintJob(printJob, this); } catch (SendIntentException sie) { Log.e(LOG_TAG, "Couldn't start print job config activity.", sie); diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java index 774f62d44045e..fd478dc12c13a 100644 --- a/services/print/java/com/android/server/print/UserState.java +++ b/services/print/java/com/android/server/print/UserState.java @@ -31,6 +31,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.ActivityOptions; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; @@ -245,10 +246,13 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks, intent.putExtra(PrintManager.EXTRA_PRINT_JOB, printJob); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); + ActivityOptions activityOptions = ActivityOptions.makeBasic() + .setPendingIntentCreatorBackgroundActivityStartMode( + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED); IntentSender intentSender = PendingIntent.getActivityAsUser( mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT - | PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, - null, new UserHandle(mUserId)) .getIntentSender(); + | PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE, + activityOptions.toBundle(), new UserHandle(mUserId)).getIntentSender(); Bundle result = new Bundle(); result.putParcelable(PrintManager.EXTRA_PRINT_JOB, printJob);