Loading src/com/android/server/telecom/TelecomServiceImpl.java +22 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; 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.Build; Loading Loading @@ -561,6 +562,9 @@ public class TelecomServiceImpl { .build(); } // Validate the profile boundary of the given image URI. validateAccountIconUserBoundary(account.getIcon()); final long token = Binder.clearCallingIdentity(); try { mPhoneAccountRegistrar.registerPhoneAccount(account); Loading Loading @@ -2576,4 +2580,22 @@ public class TelecomServiceImpl { mContext.sendBroadcast(intent); } } 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."); } } } } } tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +21 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,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.Build; Loading Loading @@ -602,6 +603,26 @@ 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 @Test public void testUnregisterPhoneAccount() throws RemoteException { Loading Loading
src/com/android/server/telecom/TelecomServiceImpl.java +22 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; 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.Build; Loading Loading @@ -561,6 +562,9 @@ public class TelecomServiceImpl { .build(); } // Validate the profile boundary of the given image URI. validateAccountIconUserBoundary(account.getIcon()); final long token = Binder.clearCallingIdentity(); try { mPhoneAccountRegistrar.registerPhoneAccount(account); Loading Loading @@ -2576,4 +2580,22 @@ public class TelecomServiceImpl { mContext.sendBroadcast(intent); } } 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."); } } } } }
tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +21 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,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.Build; Loading Loading @@ -602,6 +603,26 @@ 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 @Test public void testUnregisterPhoneAccount() throws RemoteException { Loading