summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/AttributionSource.java20
-rw-r--r--core/java/android/os/ZygoteProcess.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java27
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java27
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java6
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java10
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java1
10 files changed, 133 insertions, 10 deletions
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index 2f61fee88e9f..ec56f9a7cf0c 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -30,6 +30,7 @@ import android.os.Parcelable;
import android.os.Process;
import android.permission.PermissionManager;
import android.util.ArraySet;
+import android.util.Log;
import com.android.internal.annotations.Immutable;
@@ -86,6 +87,8 @@ import java.util.Set;
*/
@Immutable
public final class AttributionSource implements Parcelable {
+ private static final String TAG = "AttributionSource";
+
private static final String DESCRIPTOR = "android.content.AttributionSource";
private static final Binder sDefaultToken = new Binder(DESCRIPTOR);
@@ -153,9 +156,20 @@ public final class AttributionSource implements Parcelable {
AttributionSource(@NonNull Parcel in) {
this(AttributionSourceState.CREATOR.createFromParcel(in));
- // Since we just unpacked this object as part of it transiting a Binder
- // call, this is the perfect time to enforce that its UID and PID can be trusted
- enforceCallingUidAndPid();
+ if (!Binder.isHandlingTransaction()) {
+ Log.e(TAG, "Unable to verify calling UID #" + mAttributionSourceState.uid + " PID #"
+ + mAttributionSourceState.pid + " when not handling Binder transaction; "
+ + "clearing.");
+ mAttributionSourceState.pid = -1;
+ mAttributionSourceState.uid = -1;
+ mAttributionSourceState.packageName = null;
+ mAttributionSourceState.attributionTag = null;
+ mAttributionSourceState.next = null;
+ } else {
+ // Since we just unpacked this object as part of it transiting a Binder
+ // call, this is the perfect time to enforce that its UID and PID can be trusted
+ enforceCallingUidAndPid();
+ }
}
/** @hide */
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index bf2898137967..63bcf5f119e1 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -431,6 +431,8 @@ public class ZygoteProcess {
throw new ZygoteStartFailedEx("Embedded newlines not allowed");
} else if (arg.indexOf('\r') >= 0) {
throw new ZygoteStartFailedEx("Embedded carriage returns not allowed");
+ } else if (arg.indexOf('\u0000') >= 0) {
+ throw new ZygoteStartFailedEx("Embedded nulls not allowed");
}
}
@@ -972,6 +974,14 @@ public class ZygoteProcess {
return true;
}
+ for (/* NonNull */ String s : mApiDenylistExemptions) {
+ // indexOf() is intrinsified and faster than contains().
+ if (s.indexOf('\n') >= 0 || s.indexOf('\r') >= 0 || s.indexOf('\u0000') >= 0) {
+ Slog.e(LOG_TAG, "Failed to set API denylist exemptions: Bad character");
+ mApiDenylistExemptions = Collections.emptyList();
+ return false;
+ }
+ }
try {
state.mZygoteOutputWriter.write(Integer.toString(mApiDenylistExemptions.size() + 1));
state.mZygoteOutputWriter.newLine();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 0007bbde94a2..16e1563c5d27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -44,6 +44,7 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -1528,8 +1529,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
public ExpandableNotificationRow(Context context, AttributeSet attrs) {
super(context, attrs);
- mImageResolver = new NotificationInlineImageResolver(context,
- new NotificationInlineImageCache());
initDimens();
}
@@ -1558,6 +1557,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
NotificationGutsManager gutsManager,
IStatusBarService statusBarService) {
mEntry = entry;
+ mImageResolver = new NotificationInlineImageResolver(userContextForEntry(mContext, entry),
+ new NotificationInlineImageCache());
mAppName = appName;
if (mMenuRow == null) {
mMenuRow = new NotificationMenuRow(mContext, peopleNotificationIdentifier);
@@ -1591,6 +1592,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
cacheIsSystemNotification();
}
+ private static Context userContextForEntry(Context base, NotificationEntry entry) {
+ if (base.getUserId() == entry.getSbn().getNormalizedUserId()) {
+ return base;
+ }
+ return base.createContextAsUser(
+ UserHandle.of(entry.getSbn().getNormalizedUserId()), /* flags= */ 0);
+ }
+
private void initDimens() {
mMaxSmallHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_min_height_legacy);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
index 44ccb68cce4a..9cbe79e6d69a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
@@ -63,7 +63,7 @@ public class NotificationInlineImageResolver implements ImageResolver {
* @param imageCache The implementation of internal cache.
*/
public NotificationInlineImageResolver(Context context, ImageCache imageCache) {
- mContext = context.getApplicationContext();
+ mContext = context;
mImageCache = imageCache;
if (mImageCache != null) {
@@ -73,6 +73,11 @@ public class NotificationInlineImageResolver implements ImageResolver {
updateMaxImageSizes();
}
+ @VisibleForTesting
+ public Context getContext() {
+ return mContext;
+ }
+
/**
* Check if this resolver has its internal cache implementation.
* @return True if has its internal cache, false otherwise.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index 3d679deaa426..c398202a8db1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -14,6 +14,7 @@
package com.android.systemui;
+import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -28,12 +29,15 @@ import android.view.Display;
import com.android.internal.annotations.GuardedBy;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
public class SysuiTestableContext extends TestableContext {
@GuardedBy("mRegisteredReceivers")
private final Set<BroadcastReceiver> mRegisteredReceivers = new ArraySet<>();
+ private final Map<UserHandle, Context> mContextForUser = new HashMap<>();
public SysuiTestableContext(Context base) {
super(base);
@@ -113,4 +117,22 @@ public class SysuiTestableContext extends TestableContext {
}
super.unregisterReceiver(receiver);
}
+
+ /**
+ * Sets a Context object that will be returned as the result of {@link #createContextAsUser}
+ * for a specific {@code user}.
+ */
+ public void prepareCreateContextAsUser(UserHandle user, Context context) {
+ mContextForUser.put(user, context);
+ }
+
+ @Override
+ @NonNull
+ public Context createContextAsUser(UserHandle user, int flags) {
+ Context userContext = mContextForUser.get(user);
+ if (userContext != null) {
+ return userContext;
+ }
+ return super.createContextAsUser(user, flags);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index fa25c3f1e005..0bbf1223dcfc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -20,6 +20,10 @@ import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL;
+import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.PKG;
+import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.USER_HANDLE;
+
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -36,6 +40,8 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
+import android.content.Context;
+import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -46,6 +52,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.SysuiTestableContext;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
@@ -330,4 +337,24 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
assertTrue(row.getIsNonblockable());
}
+
+ @Test
+ public void imageResolver_sameNotificationUser_usesContext() throws Exception {
+ ExpandableNotificationRow row = mNotificationTestHelper.createRow(PKG,
+ USER_HANDLE.getUid(1234), USER_HANDLE);
+
+ assertThat(row.getImageResolver().getContext()).isSameInstanceAs(mContext);
+ }
+
+ @Test
+ public void imageResolver_differentNotificationUser_createsUserContext() throws Exception {
+ UserHandle user = new UserHandle(33);
+ Context userContext = new SysuiTestableContext(mContext);
+ mContext.prepareCreateContextAsUser(user, userContext);
+
+ ExpandableNotificationRow row = mNotificationTestHelper.createRow(PKG,
+ user.getUid(1234), user);
+
+ assertThat(row.getImageResolver().getContext()).isSameInstanceAs(userContext);
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index aa42e8deb581..0420d7f7f68e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -30,8 +30,10 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.content.ComponentName;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.Rect;
import android.metrics.LogMaker;
@@ -236,6 +238,31 @@ final class AutofillManagerServiceImpl
@Override // from PerUserSystemService
protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
throws NameNotFoundException {
+ final List<ResolveInfo> resolveInfos =
+ getContext().getPackageManager().queryIntentServicesAsUser(
+ new Intent(AutofillService.SERVICE_INTERFACE),
+ // The MATCH_INSTANT flag is added because curret autofill CTS module is
+ // defined in one apk, which makes the test autofill service installed in a
+ // instant app when the CTS tests are running in instant app mode.
+ // TODO: Remove MATCH_INSTANT flag after completing refactoring the CTS module
+ // to make the test autofill service a separate apk.
+ PackageManager.GET_META_DATA | PackageManager.MATCH_INSTANT,
+ mUserId);
+ boolean serviceHasAutofillIntentFilter = false;
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ if (serviceInfo.getComponentName().equals(serviceComponent)) {
+ serviceHasAutofillIntentFilter = true;
+ break;
+ }
+ }
+ if (!serviceHasAutofillIntentFilter) {
+ Slog.w(TAG,
+ "Autofill service from '" + serviceComponent.getPackageName() + "' does"
+ + "not have intent filter " + AutofillService.SERVICE_INTERFACE);
+ throw new SecurityException("Service does not declare intent filter "
+ + AutofillService.SERVICE_INTERFACE);
+ }
mInfo = new AutofillServiceInfo(getContext(), serviceComponent, mUserId);
return mInfo.getServiceInfo();
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index ff8881ba1852..6be6902ac327 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -430,10 +430,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
mCallingPackage = callingPackage;
request.setCallingPackage(callingPackage);
- if (mayAssociateWithoutPrompt(callingPackage, userId)) {
- Slog.i(LOG_TAG, "setSkipPrompt(true)");
- request.setSkipPrompt(true);
- }
+ request.setSkipPrompt(mayAssociateWithoutPrompt(callingPackage, userId));
+
callback.asBinder().linkToDeath(CompanionDeviceManagerService.this /* recipient */, 0);
AndroidFuture<String> fetchProfileDescription =
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index d9153fe44868..43944b050de4 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3558,6 +3558,11 @@ public class AccountManagerService
// Strip auth token from result.
result.remove(AccountManager.KEY_AUTHTOKEN);
+ if (!checkKeyIntent(Binder.getCallingUid(), result)) {
+ onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
+ "invalid intent in bundle returned");
+ return;
+ }
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG,
@@ -5135,6 +5140,11 @@ public class AccountManagerService
} else {
if (mStripAuthTokenFromResult) {
result.remove(AccountManager.KEY_AUTHTOKEN);
+ if (!checkKeyIntent(Binder.getCallingUid(), result)) {
+ onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
+ "invalid intent in bundle returned");
+ return;
+ }
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, getClass().getSimpleName()
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index dd8b96eab3d7..31babe0418b8 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -691,6 +691,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// TODO: switch this back to SecurityException
Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
+ permName);
+ return;
}
mRegistry.removePermission(permName);
}