mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
110 lines
5.3 KiB
Diff
110 lines
5.3 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Pranav Madapurmath <pmadapurmath@google.com>
|
||
|
Date: Wed, 5 Apr 2023 21:36:12 +0000
|
||
|
Subject: [PATCH] Resolve account image icon profile boundary exploit.
|
||
|
|
||
|
Because Telecom grants the INTERACT_ACROSS_USERS permission, an exploit
|
||
|
is possible where the user can upload an image icon (belonging to
|
||
|
another user) via registering a phone account. This CL provides a
|
||
|
lightweight solution for parsing the image URI to detect profile
|
||
|
exploitation.
|
||
|
|
||
|
Fixes: 273502295
|
||
|
Fixes: 296915211
|
||
|
Test: Unit test to enforce successful/failure path
|
||
|
(cherry picked from commit d0d1d38e37de54e58a7532a0020582fbd7d476b7)
|
||
|
(cherry picked from commit e7d0ca3fe5be6e393f643f565792ea5e7ed05f48)
|
||
|
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a604311f86ea8136ca2ac9f9ff0af7fa57ee3f42)
|
||
|
Merged-In: I2b6418f019a373ee9f02ba8683e5b694e7ab80a5
|
||
|
Change-Id: I2b6418f019a373ee9f02ba8683e5b694e7ab80a5
|
||
|
---
|
||
|
.../server/telecom/TelecomServiceImpl.java | 22 +++++++++++++++++++
|
||
|
.../telecom/tests/TelecomServiceImplTest.java | 22 +++++++++++++++++++
|
||
|
2 files changed, 44 insertions(+)
|
||
|
|
||
|
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
|
||
|
index 2f9ffdbc4..4641f5436 100644
|
||
|
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
|
||
|
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
|
||
|
@@ -35,6 +35,7 @@ import android.content.pm.PackageManager;
|
||
|
import android.content.res.Resources;
|
||
|
import android.content.pm.ParceledListSlice;
|
||
|
import android.content.pm.ResolveInfo;
|
||
|
+import android.graphics.drawable.Icon;
|
||
|
import android.net.Uri;
|
||
|
import android.os.Binder;
|
||
|
import android.os.Bundle;
|
||
|
@@ -468,6 +469,9 @@ public class TelecomServiceImpl {
|
||
|
enforceRegisterMultiUser();
|
||
|
}
|
||
|
enforceUserHandleMatchesCaller(account.getAccountHandle());
|
||
|
+ // Validate the profile boundary of the given image URI.
|
||
|
+ validateAccountIconUserBoundary(account.getIcon());
|
||
|
+
|
||
|
final long token = Binder.clearCallingIdentity();
|
||
|
try {
|
||
|
mPhoneAccountRegistrar.registerPhoneAccount(account);
|
||
|
@@ -1742,4 +1746,22 @@ public class TelecomServiceImpl {
|
||
|
// If only TX or RX were set (or neither), the video state is valid.
|
||
|
return remainingState == 0;
|
||
|
}
|
||
|
+
|
||
|
+ private void validateAccountIconUserBoundary(Icon icon) {
|
||
|
+ // 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);
|
||
|
+ if (userId != UserHandle.getUserId(Binder.getCallingUid())) {
|
||
|
+ // If we are transcending the profile boundary, throw an error.
|
||
|
+ throw new IllegalArgumentException("Attempting to register a phone account with"
|
||
|
+ + " an image icon belonging to another user.");
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
|
||
|
index 1d46f1abb..491b6183f 100644
|
||
|
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
|
||
|
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
|
||
|
@@ -28,6 +28,7 @@ import android.content.Context;
|
||
|
import android.content.Intent;
|
||
|
import android.content.pm.ApplicationInfo;
|
||
|
import android.content.pm.PackageManager;
|
||
|
+import android.graphics.drawable.Icon;
|
||
|
import android.net.Uri;
|
||
|
import android.os.Binder;
|
||
|
import android.os.Bundle;
|
||
|
@@ -478,6 +479,27 @@ public class TelecomServiceImplTest extends TelecomTestCase {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ @SmallTest
|
||
|
+ @Test
|
||
|
+ public void testRegisterPhoneAccountImageIconCrossUser() throws RemoteException {
|
||
|
+ String packageNameToUse = "com.android.officialpackage";
|
||
|
+ PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
|
||
|
+ packageNameToUse, "cs"), "test", Binder.getCallingUserHandle());
|
||
|
+ Icon icon = Icon.createWithContentUri("content://10@media/external/images/media/");
|
||
|
+ PhoneAccount phoneAccount = makePhoneAccount(phHandle).setIcon(icon).build();
|
||
|
+ doReturn(PackageManager.PERMISSION_GRANTED)
|
||
|
+ .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
|
||
|
+
|
||
|
+ // This should fail; security exception will be thrown.
|
||
|
+ registerPhoneAccountTestHelper(phoneAccount, false);
|
||
|
+
|
||
|
+ icon = Icon.createWithContentUri("content://0@media/external/images/media/");
|
||
|
+ phoneAccount = makePhoneAccount(phHandle).setIcon(icon).build();
|
||
|
+ // This should succeed.
|
||
|
+ registerPhoneAccountTestHelper(phoneAccount, true);
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
@SmallTest
|
||
|
public void testUnregisterPhoneAccount() throws RemoteException {
|
||
|
String packageNameToUse = "com.android.officialpackage";
|