2023-08-08 05:30:19 -04:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Pranav Madapurmath <pmadapurmath@google.com>
|
|
|
|
Date: Thu, 25 May 2023 21:58:19 +0000
|
|
|
|
Subject: [PATCH] Resolve StatusHints image exploit across user.
|
|
|
|
|
|
|
|
Because of the INTERACT_ACROSS_USERS permission, an app that implements
|
|
|
|
a ConnectionService can upload an image icon belonging to another user
|
|
|
|
by setting it in the StatusHints. Validating the construction of the
|
|
|
|
StatusHints on the calling user would prevent a malicious app from
|
|
|
|
registering a connection service with the embedded image icon from a
|
|
|
|
different user.
|
|
|
|
|
|
|
|
From additional feedback, this CL also addresses potential
|
|
|
|
vulnerabilities in an app being able to directly invoke the binder for a
|
|
|
|
means to manipulate the contents of the bundle that are passed with it.
|
|
|
|
The targeted points of entry are in ConnectionServiceWrapper for the
|
|
|
|
following APIs: handleCreateConnectionComplete, setStatusHints,
|
|
|
|
addConferenceCall, and addExistingConnection.
|
|
|
|
|
|
|
|
Fixes: 280797684
|
|
|
|
Test: Manual (verified that original exploit is no longer an issue).
|
|
|
|
Test: Unit test for validating image in StatusHints constructor.
|
|
|
|
Test: Unit tests to address vulnerabilities via the binder.
|
|
|
|
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:48223d6034907349c6a3fab3018c1b37d86367af)
|
|
|
|
Merged-In: I6e70e238b3a5ace1cab41ec5796a6bb4d79769f2
|
|
|
|
Change-Id: I6e70e238b3a5ace1cab41ec5796a6bb4d79769f2
|
|
|
|
---
|
|
|
|
.../android/telecom/ParcelableConference.java | 8 +++
|
|
|
|
.../java/android/telecom/StatusHints.java | 53 ++++++++++++++++++-
|
|
|
|
2 files changed, 59 insertions(+), 2 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/telecomm/java/android/telecom/ParcelableConference.java b/telecomm/java/android/telecom/ParcelableConference.java
|
|
|
|
index ede05943772e..b2f8ac8cb0ec 100644
|
|
|
|
--- a/telecomm/java/android/telecom/ParcelableConference.java
|
|
|
|
+++ b/telecomm/java/android/telecom/ParcelableConference.java
|
|
|
|
@@ -155,6 +155,14 @@ public final class ParcelableConference implements Parcelable {
|
|
|
|
return mAddressPresentation;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ public String getCallerDisplayName() {
|
|
|
|
+ return mCallerDisplayName;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public int getCallerDisplayNamePresentation() {
|
|
|
|
+ return mCallerDisplayNamePresentation;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
public static final @android.annotation.NonNull Parcelable.Creator<ParcelableConference> CREATOR =
|
|
|
|
new Parcelable.Creator<ParcelableConference> () {
|
|
|
|
@Override
|
|
|
|
diff --git a/telecomm/java/android/telecom/StatusHints.java b/telecomm/java/android/telecom/StatusHints.java
|
2023-08-09 05:30:36 -04:00
|
|
|
index 762c93a49022..761eab81eb62 100644
|
2023-08-08 05:30:19 -04:00
|
|
|
--- a/telecomm/java/android/telecom/StatusHints.java
|
|
|
|
+++ b/telecomm/java/android/telecom/StatusHints.java
|
|
|
|
@@ -16,14 +16,19 @@
|
|
|
|
|
|
|
|
package android.telecom;
|
|
|
|
|
|
|
|
+import android.annotation.Nullable;
|
|
|
|
import android.annotation.SystemApi;
|
|
|
|
import android.content.ComponentName;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
import android.graphics.drawable.Icon;
|
|
|
|
+import android.os.Binder;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Parcel;
|
|
|
|
import android.os.Parcelable;
|
|
|
|
+import android.os.UserHandle;
|
|
|
|
+
|
|
|
|
+import com.android.internal.annotations.VisibleForTesting;
|
|
|
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
@@ -33,7 +38,7 @@ import java.util.Objects;
|
|
|
|
public final class StatusHints implements Parcelable {
|
|
|
|
|
|
|
|
private final CharSequence mLabel;
|
|
|
|
- private final Icon mIcon;
|
|
|
|
+ private Icon mIcon;
|
|
|
|
private final Bundle mExtras;
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -48,10 +53,30 @@ public final class StatusHints implements Parcelable {
|
|
|
|
|
|
|
|
public StatusHints(CharSequence label, Icon icon, Bundle extras) {
|
|
|
|
mLabel = label;
|
|
|
|
- mIcon = icon;
|
|
|
|
+ mIcon = validateAccountIconUserBoundary(icon, Binder.getCallingUserHandle());
|
|
|
|
mExtras = extras;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * @param icon
|
|
|
|
+ * @hide
|
|
|
|
+ */
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ public StatusHints(@Nullable Icon icon) {
|
|
|
|
+ mLabel = null;
|
|
|
|
+ mExtras = null;
|
|
|
|
+ mIcon = icon;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ *
|
|
|
|
+ * @param icon
|
|
|
|
+ * @hide
|
|
|
|
+ */
|
|
|
|
+ public void setIcon(@Nullable Icon icon) {
|
|
|
|
+ mIcon = icon;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
/**
|
|
|
|
* @return A package used to load the icon.
|
|
|
|
*
|
|
|
|
@@ -112,6 +137,30 @@ public final class StatusHints implements Parcelable {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Validates the StatusHints image icon to see if it's not in the calling user space.
|
|
|
|
+ * Invalidates the icon if so, otherwise returns back the original icon.
|
|
|
|
+ *
|
|
|
|
+ * @param icon
|
|
|
|
+ * @return icon (validated)
|
|
|
|
+ * @hide
|
|
|
|
+ */
|
|
|
|
+ public static Icon validateAccountIconUserBoundary(Icon icon, UserHandle callingUserHandle) {
|
|
|
|
+ // Refer to Icon#getUriString for context. The URI string is invalid for icons of
|
|
|
|
+ // incompatible types.
|
|
|
|
+ if (icon != null && (icon.getType() == Icon.TYPE_URI
|
|
|
|
+ /*|| icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP*/)) {
|
|
|
|
+ String encodedUser = icon.getUri().getEncodedUserInfo();
|
|
|
|
+ // If there is no encoded user, the URI is calling into the calling user space
|
|
|
|
+ if (encodedUser != null) {
|
|
|
|
+ int userId = Integer.parseInt(encodedUser);
|
|
|
|
+ // Do not try to save the icon if the user id isn't in the calling user space.
|
|
|
|
+ if (userId != callingUserHandle.getIdentifier()) return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return icon;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
@Override
|
|
|
|
public void writeToParcel(Parcel out, int flags) {
|
|
|
|
out.writeCharSequence(mLabel);
|