diff options
author | Kevin F. Haggerty <haggertk@lineageos.org> | 2020-05-05 07:27:40 -0600 |
---|---|---|
committer | Kevin F. Haggerty <haggertk@lineageos.org> | 2020-05-05 07:27:40 -0600 |
commit | 5df8608656b363f13049855431e2618dd153edaf (patch) | |
tree | 86fbabfd8a6b3a8ea13600745f92bdc24df3f7b3 | |
parent | e740651c8005fa64e0f022fb33c711a72a4acbcc (diff) | |
parent | 39c9bf27471f6454202236f88c247fef4c4b2b2e (diff) | |
download | android_frameworks_base-lineage-16.0.tar.gz android_frameworks_base-lineage-16.0.tar.bz2 android_frameworks_base-lineage-16.0.zip |
Merge tag 'android-9.0.0_r56' of https://android.googlesource.com/platform/frameworks/base into staging/lineage-16.0_merge-android-9.0.0_r56lineage-16.0
Android 9.0.0 release 56
* tag 'android-9.0.0_r56' of https://android.googlesource.com/platform/frameworks/base:
Verify all possible hosts that match web nav
RESTRICT AUTOMERGE Prevent accessing companion records from arbitrary uids
Revert "DO NOT MERGE - Kill apps outright for API contract violations"
RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo
RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities
DO NOT MERGE - Kill apps outright for API contract violations
DO NOT MERGE Ensure package names read from config are system packages.
RESTRICT AUTOMERGE Update keyguard locked state from TrustManagerService
Only suspend package from system or shell
Change-Id: I678145bad18e8b34e462cde9f79f2952085f5e55
12 files changed, 143 insertions, 27 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 34d26f0da90..af1a6fa9e3c 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3141,6 +3141,11 @@ <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" android:protectionLevel="signature|privileged" /> + <!-- Allows an application to manage the companion devices. + @hide --> + <permission android:name="android.permission.MANAGE_COMPANION_DEVICES" + android:protectionLevel="signature" /> + <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features. <p>Not for use by third-party applications. @hide diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index fe05c13c999..6be2da24e63 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -691,6 +691,17 @@ public class KeyStore { return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword); } + /** + * Notify keystore about the latest user locked state. This is to support keyguard-bound key. + */ + public void onUserLockedStateChanged(int userHandle, boolean locked) { + try { + mBinder.onKeyguardVisibilityChanged(locked, userHandle); + } catch (RemoteException e) { + Log.w(TAG, "Failed to update user locked state " + userHandle, e); + } + } + public int attestKey( String alias, KeymasterArguments params, KeymasterCertificateChain outChain) { try { diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index d44fe4dbc45..bf2b83b1b24 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -629,6 +629,11 @@ public class CompanionDeviceManagerService extends SystemService implements Bind + "associate USER_ID PACKAGE MAC_ADDRESS\n" + "disassociate USER_ID PACKAGE MAC_ADDRESS"; + ShellCmd() { + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_COMPANION_DEVICES, "ShellCmd"); + } + @Override public int onCommand(String cmd) { switch (cmd) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f7b2c403aa6..29adc788dfe 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7673,7 +7673,7 @@ public class ActivityManagerService extends IActivityManager.Stub } @GuardedBy("this") - private final boolean attachApplicationLocked(IApplicationThread thread, + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { // Find the application record that is being attached... either via @@ -8054,6 +8054,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final void attachApplication(IApplicationThread thread, long startSeq) { + if (thread == null) { + throw new SecurityException("Invalid application interface"); + } synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 5f2a65a7016..dddcc9e466a 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -3945,6 +3945,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { + if (srec.app == null || srec.app.thread == null) { + // Nothing to do if the caller is not attached, because this method should be called + // from an alive activity. + return false; + } final TaskRecord task = srec.getTask(); final ArrayList<ActivityRecord> activities = task.mActivities; final int start = activities.indexOf(srec); @@ -3996,14 +4001,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } if (parent != null && foundParentInTask) { + final int callingUid = srec.info.applicationInfo.uid; final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { - parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent, - srec.packageName); + parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( @@ -4016,10 +4021,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai .setActivityInfo(aInfo) .setResultTo(parent.appToken) .setCallingPid(-1) - .setCallingUid(parent.launchedFromUid) - .setCallingPackage(parent.launchedFromPackage) + .setCallingUid(callingUid) + .setCallingPackage(srec.packageName) .setRealCallingPid(-1) - .setRealCallingUid(parent.launchedFromUid) + .setRealCallingUid(callingUid) .setComponentSpecified(true) .execute(); foundParentInTask = res == ActivityManager.START_SUCCESS; diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java index c926503da27..240f01d159a 100644 --- a/services/core/java/com/android/server/am/ActivityStartController.java +++ b/services/core/java/com/android/server/am/ActivityStartController.java @@ -334,6 +334,9 @@ public class ActivityStartController { } else { callingPid = callingUid = -1; } + boolean forceNewTask = false; + final int filterCallingUid = ActivityStarter.computeResolveFilterUid( + callingUid, realCallingUid, UserHandle.USER_NULL); final long origId = Binder.clearCallingIdentity(); try { synchronized (mService) { @@ -353,11 +356,13 @@ public class ActivityStartController { // Don't modify the client's object! intent = new Intent(intent); + if (forceNewTask) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } // Collect information about the target of the Intent. ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, - null, userId, ActivityStarter.computeResolveFilterUid( - callingUid, realCallingUid, UserHandle.USER_NULL)); + null, userId, filterCallingUid); // TODO: New, check if this is correct aInfo = mService.getActivityInfoForUser(aInfo, userId); @@ -397,7 +402,17 @@ public class ActivityStartController { return res; } - resultTo = outActivity[0] != null ? outActivity[0].appToken : null; + final ActivityRecord started = outActivity[0]; + if (started != null && started.getUid() == filterCallingUid) { + // Only the started activity which has the same uid as the source caller can + // be the caller of next activity. + resultTo = started.appToken; + forceNewTask = false; + } else { + // Different apps not adjacent to the caller are forced to be new task. + resultTo = null; + forceNewTask = true; + } } } } finally { diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 8ead96ae346..7a005f665a1 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7202,6 +7202,7 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting protected void simulatePackageSuspendBroadcast(boolean suspend, String pkg) { + checkCallerIsSystemOrShell(); // only use for testing: mimic receive broadcast that package is (un)suspended // but does not actually (un)suspend the package final Bundle extras = new Bundle(); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index cab17674469..99f4f6fe171 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17855,7 +17855,9 @@ public class PackageManagerService extends IPackageManager.Stub final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { + // Run verification against hosts mentioned in any web-nav intent filter, + // even if the filter matches non-web schemes as well + if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) { if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString()); mIntentFilterVerifier.addOneIntentFilterVerification( @@ -20794,7 +20796,29 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public String getSystemTextClassifierPackageName() { - return mContext.getString(R.string.config_defaultTextClassifierPackage); + return ensureSystemPackageName(mContext.getString( + R.string.config_defaultTextClassifierPackage)); + } + + @Nullable + private String ensureSystemPackageName(@Nullable String packageName) { + if (packageName == null) { + return null; + } + long token = Binder.clearCallingIdentity(); + try { + if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) { + PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM); + if (packageInfo != null) { + EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid, + ""); + } + return null; + } + } finally { + Binder.restoreCallingIdentity(token); + } + return packageName; } @Override diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index c6d85a83f21..dbf96aa9eee 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -20,8 +20,6 @@ import android.app.ActivityManager; import android.content.Context; import android.content.ContentResolver; import android.os.RemoteException; -import android.os.ServiceManager; -import android.security.IKeystoreService; import android.util.Slog; import com.android.internal.policy.IKeyguardService; @@ -61,17 +59,12 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { private IUsbRestrict mUsbRestrictor = null; private ContentResolver mContentResolver; - IKeystoreService mKeystoreService; - public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) { mLockPatternUtils = new LockPatternUtils(context); mCurrentUserId = ActivityManager.getCurrentUser(); mCallback = callback; mContentResolver = context.getContentResolver(); - mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager - .getService("android.security.keystore")); - try { service.addStateMonitorCallback(this); } catch (RemoteException e) { @@ -104,11 +97,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mIsShowing = showing; mCallback.onShowingChanged(); - try { - mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId); - } catch (RemoteException e) { - Slog.e(TAG, "Error informing keystore of screen lock", e); - } if (mUsbRestrictor == null) { try { @@ -144,10 +132,6 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mCurrentUserId = userId; } - private synchronized int getCurrentUser() { - return mCurrentUserId; - } - @Override // Binder interface public void onInputRestrictedStateChanged(boolean inputRestricted) { mInputRestricted = inputRestricted; diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index f9f4bbfc8eb..0c22f2f1c18 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -47,6 +47,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.security.KeyStore; import android.service.trust.TrustAgentService; import android.text.TextUtils; import android.util.ArraySet; @@ -121,6 +122,33 @@ public class TrustManagerService extends SystemService { @GuardedBy("mUserIsTrusted") private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); + /** + * Stores the locked state for users on the device. There are three different type of users + * which are handled slightly differently: + * <ul> + * <li> Users with real keyguard + * These are users who can be switched to ({@link UserInfo#supportsSwitchToByUser()}). Their + * locked state is derived by a combination of user secure state, keyguard state, trust agent + * decision and biometric authentication result. These are updated via + * {@link #refreshDeviceLockedForUser(int)} and result stored in {@link #mDeviceLockedForUser}. + * <li> Managed profiles with unified challenge + * Managed profile with unified challenge always shares the same locked state as their parent, + * so their locked state is not recorded in {@link #mDeviceLockedForUser}. Instead, + * {@link ITrustManager#isDeviceLocked(int)} always resolves their parent user handle and + * queries its locked state instead. + * <li> Managed profiles with separate challenge + * Locked state for profile with separate challenge is determined by other parts of the + * framework (mostly PowerManager) and pushed to TrustManagerService via + * {@link ITrustManager#setDeviceLockedForUser(int, boolean)}. Although in a corner case when + * the profile has a separate but empty challenge, setting its {@link #mDeviceLockedForUser} to + * {@code false} is actually done by {@link #refreshDeviceLockedForUser(int)}. + * </ul> + * TODO: Rename {@link ITrustManager#setDeviceLockedForUser(int, boolean)} to + * {@code setDeviceLockedForProfile} to better reflect its purpose. Unifying + * {@code setDeviceLockedForProfile} and {@link #setDeviceLockedForUser} would also be nice. + * At the moment they both update {@link #mDeviceLockedForUser} but have slightly different + * side-effects: one notifies trust agents while the other sends out a broadcast. + */ @GuardedBy("mDeviceLockedForUser") private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray(); @@ -410,6 +438,10 @@ public class TrustManagerService extends SystemService { } } + /** + * Update the user's locked state. Only applicable to users with a real keyguard + * ({@link UserInfo#supportsSwitchToByUser}) and unsecured managed profiles. + */ private void refreshDeviceLockedForUser(int userId) { if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) { Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle," @@ -470,6 +502,15 @@ public class TrustManagerService extends SystemService { } if (changed) { dispatchDeviceLocked(userId, locked); + + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); + // Also update the user's profiles who have unified challenge, since they + // share the same unlocked state (see {@link #isDeviceLocked(int)}) + for (int profileHandle : mUserManager.getEnabledProfileIds(userId)) { + if (mLockPatternUtils.isManagedProfileWithUnifiedChallenge(profileHandle)) { + KeyStore.getInstance().onUserLockedStateChanged(profileHandle, locked); + } + } } } @@ -992,6 +1033,10 @@ public class TrustManagerService extends SystemService { return "0x" + Integer.toHexString(i); } + /** + * Changes the lock status for the given user. This is only applicable to managed profiles, + * other users should be handled by Keyguard. + */ @Override public void setDeviceLockedForUser(int userId, boolean locked) { enforceReportPermission(); @@ -1002,6 +1047,9 @@ public class TrustManagerService extends SystemService { synchronized (mDeviceLockedForUser) { mDeviceLockedForUser.put(userId, locked); } + + KeyStore.getInstance().onUserLockedStateChanged(userId, locked); + if (locked) { try { ActivityManager.getService().notifyLockedProfile(userId); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java index 01425ed51b5..55ece4cf03d 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java @@ -606,6 +606,19 @@ public class ActivityStackTests extends ActivityTestsBase { assertTrue(listener.changed); } + @Test + public void testNavigateUpTo() { + final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask) + .setUid(firstActivity.getUid() + 1).build(); + secondActivity.app.thread = null; + // This should do nothing from a non-attached caller (app.thread == null). + assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */, + firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */)); + assertFalse(secondActivity.finishing); + assertFalse(firstActivity.finishing); + } + private void verifyShouldSleepActivities(boolean focusedStack, boolean keyguardGoingAway, boolean displaySleeping, boolean expected) { mSupervisor.mFocusedStack = focusedStack ? mStack : null; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index 1cd111fce0e..6467dbd8570 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -192,6 +192,8 @@ public class ActivityTestsBase { aInfo.applicationInfo = new ApplicationInfo(); aInfo.applicationInfo.packageName = mComponent.getPackageName(); aInfo.applicationInfo.uid = mUid; + aInfo.packageName = mComponent.getPackageName(); + aInfo.name = mComponent.getClassName(); aInfo.flags |= mActivityFlags; final ActivityRecord activity = new ActivityRecord(mService, null /* caller */, |