diff options
author | 2025-01-02 14:58:50 -0800 | |
---|---|---|
committer | 2025-01-03 13:38:19 -0800 | |
commit | 9a260d5e11ce9b4b794079baaee8ecba96d5116b (patch) | |
tree | f8610b5c91a321ea3c64e5a19c7df585e6a94028 /telecomm | |
parent | 781d348b9906403f53b1610bd17c63fd9906c96a (diff) |
Resolve cross account user icon validation.
Resolves a vulnerability found with the cross account user icon
validation in StatusHint and TelecomServiceImpl (when registering a
phone account). The reporter found that an uri formatted as `userId%`
isn't parsed properly with the existing reference to Uri.encodedUserInfo.
Bug: 376461551
Bug: 376259166
Flag: EXEMPT bugfix
Test: atest TelecomServiceImplTest
Change-Id: I25614ead889501f4553ed2b42b366e09a47b0c9f
Diffstat (limited to 'telecomm')
-rw-r--r-- | telecomm/java/android/telecom/StatusHints.java | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/telecomm/java/android/telecom/StatusHints.java b/telecomm/java/android/telecom/StatusHints.java index 5f0c8d729e74..31b84ff04b85 100644 --- a/telecomm/java/android/telecom/StatusHints.java +++ b/telecomm/java/android/telecom/StatusHints.java @@ -27,6 +27,7 @@ import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -40,6 +41,7 @@ public final class StatusHints implements Parcelable { private final CharSequence mLabel; private Icon mIcon; private final Bundle mExtras; + private static final String TAG = StatusHints.class.getSimpleName(); /** * @hide @@ -150,17 +152,37 @@ public final class StatusHints implements Parcelable { // 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; + int callingUserId = callingUserHandle.getIdentifier(); + int requestingUserId = getUserIdFromAuthority( + icon.getUri().getAuthority(), callingUserId); + if (callingUserId != requestingUserId) { + return null; } + } return icon; } + /** + * Derives the user id from the authority or the default user id if none could be found. + * @param auth + * @param defaultUserId + * @return The user id from the given authority. + * @hide + */ + public static int getUserIdFromAuthority(String auth, int defaultUserId) { + if (auth == null) return defaultUserId; + int end = auth.lastIndexOf('@'); + if (end == -1) return defaultUserId; + String userIdString = auth.substring(0, end); + try { + return Integer.parseInt(userIdString); + } catch (NumberFormatException e) { + Log.w(TAG, "Error parsing userId." + e); + return UserHandle.USER_NULL; + } + } + @Override public void writeToParcel(Parcel out, int flags) { out.writeCharSequence(mLabel); |