diff options
5 files changed, 68 insertions, 60 deletions
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index 68679c794c35..6f7d20a950d5 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -455,8 +455,7 @@ public class BugreportProgressService extends Service { intent.putExtra(DevicePolicyManager.EXTRA_REMOTE_BUGREPORT_HASH, bugreportHash); intent.putExtra(DevicePolicyManager.EXTRA_REMOTE_BUGREPORT_NONCE, nonce); intent.putExtra(EXTRA_BUGREPORT, bugreportFileName); - context.sendBroadcastAsUser(intent, UserHandle.SYSTEM, - android.Manifest.permission.DUMP); + context.sendBroadcast(intent, android.Manifest.permission.DUMP); } /** diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b62937847ea9..5a27af057ec9 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7438,10 +7438,11 @@ public class ActivityManagerService extends IActivityManager.Stub if (shareDescription != null) { triggerShellBugreport.putExtra(EXTRA_DESCRIPTION, shareDescription); } + UserHandle callingUser = Binder.getCallingUserHandle(); final long identity = Binder.clearCallingIdentity(); try { // Send broadcast to shell to trigger bugreport using Bugreport API - mContext.sendBroadcastAsUser(triggerShellBugreport, UserHandle.SYSTEM); + mContext.sendBroadcastAsUser(triggerShellBugreport, callingUser); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/incident/IncidentCompanionService.java b/services/core/java/com/android/server/incident/IncidentCompanionService.java index 87fe785ca614..b8e7d4971790 100644 --- a/services/core/java/com/android/server/incident/IncidentCompanionService.java +++ b/services/core/java/com/android/server/incident/IncidentCompanionService.java @@ -34,7 +34,6 @@ import android.os.IncidentManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; -import android.os.UserManager; import android.util.Log; import com.android.internal.util.DumpUtils; @@ -128,21 +127,21 @@ public class IncidentCompanionService extends SystemService { try { final Context context = getContext(); - final int primaryUser = getAndValidateUser(context); - if (primaryUser == UserHandle.USER_NULL) { + // Get the current admin user. Only they can do incident reports. + final int currentAdminUser = getCurrentUserIfAdmin(); + if (currentAdminUser == UserHandle.USER_NULL) { return; } final Intent intent = new Intent(Intent.ACTION_INCIDENT_REPORT_READY); intent.setComponent(new ComponentName(pkg, cls)); - Log.d(TAG, "sendReportReadyBroadcast sending primaryUser=" + primaryUser - + " userHandle=" + UserHandle.getUserHandleForUid(primaryUser) + Log.d(TAG, "sendReportReadyBroadcast sending currentUser=" + currentAdminUser + + " userHandle=" + UserHandle.of(currentAdminUser) + " intent=" + intent); - // Send it to the primary user. Only they can do incident reports. context.sendBroadcastAsUserMultiplePermissions(intent, - UserHandle.getUserHandleForUid(primaryUser), + UserHandle.of(currentAdminUser), DUMP_AND_USAGE_STATS_PERMISSIONS); } finally { Binder.restoreCallingIdentity(ident); @@ -414,10 +413,10 @@ public class IncidentCompanionService extends SystemService { } /** - * Check whether the current user is the primary user, and return the user id if they are. + * Check whether the current user is an admin user, and return the user id if they are. * Returns UserHandle.USER_NULL if not valid. */ - public static int getAndValidateUser(Context context) { + public static int getCurrentUserIfAdmin() { // Current user UserInfo currentUser; try { @@ -427,28 +426,21 @@ public class IncidentCompanionService extends SystemService { throw new RuntimeException(ex); } - // Primary user - final UserManager um = UserManager.get(context); - final UserInfo primaryUser = um.getPrimaryUser(); - // Check that we're using the right user. if (currentUser == null) { Log.w(TAG, "No current user. Nobody to approve the report." + " The report will be denied."); return UserHandle.USER_NULL; } - if (primaryUser == null) { - Log.w(TAG, "No primary user. Nobody to approve the report." - + " The report will be denied."); - return UserHandle.USER_NULL; - } - if (primaryUser.id != currentUser.id) { - Log.w(TAG, "Only the primary user can approve bugreports, but they are not" - + " the current user. The report will be denied."); + + if (!currentUser.isAdmin()) { + Log.w(TAG, "Only an admin user running in foreground can approve " + + "bugreports, but the current foreground user is not an admin user. " + + "The report will be denied."); return UserHandle.USER_NULL; } - return primaryUser.id; + return currentUser.id; } } diff --git a/services/core/java/com/android/server/incident/PendingReports.java b/services/core/java/com/android/server/incident/PendingReports.java index f39bebf060f7..684b5f16e999 100644 --- a/services/core/java/com/android/server/incident/PendingReports.java +++ b/services/core/java/com/android/server/incident/PendingReports.java @@ -16,6 +16,7 @@ package com.android.server.incident; +import android.annotation.UserIdInt; import android.app.AppOpsManager; import android.app.BroadcastOptions; import android.content.ComponentName; @@ -30,6 +31,7 @@ import android.os.IncidentManager; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; +import android.os.UserManager; import android.util.Log; import java.io.FileDescriptor; @@ -272,15 +274,22 @@ class PendingReports { return; } - // Find the primary user of this device. - final int primaryUser = getAndValidateUser(); - if (primaryUser == UserHandle.USER_NULL) { + // Find the current user of the device and check if they are an admin. + final int currentAdminUser = getCurrentUserIfAdmin(); + final int callingUser = UserHandle.getUserId(callingUid); + + // Deny the report if the current admin user is null + // or the calling user is not from the same profile group of current user. + if (currentAdminUser == UserHandle.USER_NULL + || !isSameProfileGroupUser(callingUser, currentAdminUser)) { + Log.w(TAG, "Calling user " + callingUser + " doesn't belong to the same profile " + + "group of the current admin user " + currentAdminUser); denyReportBeforeAddingRec(listener, callingPackage); return; } // Find the approver app (hint: it's PermissionController). - final ComponentName receiver = getApproverComponent(primaryUser); + final ComponentName receiver = getApproverComponent(currentAdminUser); if (receiver == null) { // We couldn't find an approver... so deny the request here and now, before we // do anything else. @@ -298,26 +307,26 @@ class PendingReports { try { listener.asBinder().linkToDeath(() -> { Log.i(TAG, "Got death notification listener=" + listener); - cancelReportImpl(listener, receiver, primaryUser); + cancelReportImpl(listener, receiver, currentAdminUser); }, 0); } catch (RemoteException ex) { Log.e(TAG, "Remote died while trying to register death listener: " + rec.getUri()); // First, remove from our list. - cancelReportImpl(listener, receiver, primaryUser); + cancelReportImpl(listener, receiver, currentAdminUser); } // Go tell Permission controller to start asking the user. - sendBroadcast(receiver, primaryUser); + sendBroadcast(receiver, currentAdminUser); } /** * Cancel a pending report request (because of an explicit call to cancel) */ private void cancelReportImpl(IIncidentAuthListener listener) { - final int primaryUser = getAndValidateUser(); - final ComponentName receiver = getApproverComponent(primaryUser); - if (primaryUser != UserHandle.USER_NULL && receiver != null) { - cancelReportImpl(listener, receiver, primaryUser); + final int currentAdminUser = getCurrentUserIfAdmin(); + final ComponentName receiver = getApproverComponent(currentAdminUser); + if (currentAdminUser != UserHandle.USER_NULL && receiver != null) { + cancelReportImpl(listener, receiver, currentAdminUser); } } @@ -326,13 +335,13 @@ class PendingReports { * by the calling app, or because of a binder death). */ private void cancelReportImpl(IIncidentAuthListener listener, ComponentName receiver, - int primaryUser) { + @UserIdInt int user) { // First, remove from our list. synchronized (mLock) { removePendingReportRecLocked(listener); } // Second, call back to PermissionController to say it's canceled. - sendBroadcast(receiver, primaryUser); + sendBroadcast(receiver, user); } /** @@ -342,21 +351,21 @@ class PendingReports { * cleanup cases to keep the apps' list in sync with ours. */ private void sendBroadcast() { - final int primaryUser = getAndValidateUser(); - if (primaryUser == UserHandle.USER_NULL) { + final int currentAdminUser = getCurrentUserIfAdmin(); + if (currentAdminUser == UserHandle.USER_NULL) { return; } - final ComponentName receiver = getApproverComponent(primaryUser); + final ComponentName receiver = getApproverComponent(currentAdminUser); if (receiver == null) { return; } - sendBroadcast(receiver, primaryUser); + sendBroadcast(receiver, currentAdminUser); } /** * Send the confirmation broadcast. */ - private void sendBroadcast(ComponentName receiver, int primaryUser) { + private void sendBroadcast(ComponentName receiver, int currentUser) { final Intent intent = new Intent(Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED); intent.setComponent(receiver); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); @@ -364,8 +373,8 @@ class PendingReports { final BroadcastOptions options = BroadcastOptions.makeBasic(); options.setBackgroundActivityStartsAllowed(true); - // Send it to the primary user. - mContext.sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(primaryUser), + // Send it to the current user. + mContext.sendBroadcastAsUser(intent, UserHandle.of(currentUser), android.Manifest.permission.APPROVE_INCIDENT_REPORTS, options.toBundle()); } @@ -420,11 +429,11 @@ class PendingReports { } /** - * Check whether the current user is the primary user, and return the user id if they are. + * Check whether the current user is an admin user, and return the user id if they are. * Returns UserHandle.USER_NULL if not valid. */ - private int getAndValidateUser() { - return IncidentCompanionService.getAndValidateUser(mContext); + private int getCurrentUserIfAdmin() { + return IncidentCompanionService.getCurrentUserIfAdmin(); } /** @@ -461,5 +470,15 @@ class PendingReports { return false; } } + + /** + * Checks if the 2 provided user ids belong to the same profile group + * using {@link UserManager#isSameProfileGroup(int, int)} + */ + private boolean isSameProfileGroupUser(@UserIdInt int currentAdminUser, + @UserIdInt int callingUser) { + return UserManager.get(mContext) + .isSameProfileGroup(currentAdminUser, callingUser); + } } diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java index 58428ca48c97..2fdc4cd5f7c1 100644 --- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java +++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java @@ -33,8 +33,8 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; -import android.os.UserManager; import android.telephony.TelephonyManager; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Slog; @@ -189,10 +189,10 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { } /** - * Validates that the current user is the primary user or when bugreport is requested remotely - * and current user is affiliated user. + * Validates that the current user is an admin user or, when bugreport is requested remotely + * that the current user is an affiliated user. * - * @throws IllegalArgumentException if the current user is not the primary user + * @throws IllegalArgumentException if the current user is not an admin user */ private void ensureUserCanTakeBugReport(int bugreportMode) { UserInfo currentUser = null; @@ -202,20 +202,17 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { // Impossible to get RemoteException for an in-process call. } - UserInfo primaryUser = UserManager.get(mContext).getPrimaryUser(); if (currentUser == null) { - logAndThrow("No current user. Only primary user is allowed to take bugreports."); + logAndThrow("There is no current user, so no bugreport can be requested."); } - if (primaryUser == null) { - logAndThrow("No primary user. Only primary user is allowed to take bugreports."); - } - if (primaryUser.id != currentUser.id) { + + if (!currentUser.isAdmin()) { if (bugreportMode == BugreportParams.BUGREPORT_MODE_REMOTE && isCurrentUserAffiliated(currentUser.id)) { return; } - logAndThrow("Current user not primary user. Only primary user" - + " is allowed to take bugreports."); + logAndThrow(TextUtils.formatSimple("Current user %s is not an admin user." + + " Only admin users are allowed to take bugreport.", currentUser.id)); } } |