Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfc855ba authored by Grant Menke's avatar Grant Menke
Browse files

Resolve cross account user ringtone validation.

Resolves a vulnerability found with the lack of cross account user ringtone
validation in RingtoneFactory. The reporter found that a ringtone file owned by a different user can be accessed and played by the user who does not own that file.

Bug: 356604577
Flag: EXEMPT Critical CVE bugfix
Test: RingtoneFactoryTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1c7fbd70da65f7b2dd561af8ec9f94b81acf5baa)
Merged-In: Ie28e8d0890086caada561ed27dd660836e6aa6bb
Change-Id: Ie28e8d0890086caada561ed27dd660836e6aa6bb
parent 0e7ac12f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3151,7 +3151,8 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        return Contacts.getLookupUri(mCallerInfo.getContactId(), mCallerInfo.lookupKey);
    }

    Uri getRingtone() {
    @VisibleForTesting
    public Uri getRingtone() {
        return mCallerInfo == null ? null : mCallerInfo.contactRingtoneUri;
    }

+27 −6
Original line number Diff line number Diff line
@@ -80,13 +80,19 @@ public class RingtoneFactory {
        Ringtone ringtone = null;

        if (ringtoneUri != null && userContext != null) {
            // Ringtone URI is explicitly specified. First, try to create a Ringtone with that.
            if (currentUserOwnsRingtone(ringtoneUri, incomingCall)) {
                // Ringtone URI is explicitly specified and owned by the current user - try to
                // create a Ringtone with that.
                try {
                    ringtone = RingtoneManager.getRingtone(
                            userContext, ringtoneUri, volumeShaperConfig, audioAttrs);
                } catch (Exception e) {
                    Log.e(this, e, "getRingtone: exception while getting ringtone.");
                }
            } else {
                Log.w(this, "getRingtone: Failed to verify that the custom ringtone URI"
                        + " is owned by the current user. Falling back to the default ringtone.");
            }
        }
        if (ringtone == null) {
            // Contact didn't specify ringtone or custom Ringtone creation failed. Get default
@@ -120,6 +126,21 @@ public class RingtoneFactory {
        return ringtone;
    }

    private static boolean currentUserOwnsRingtone(Uri ringtoneUri, Call incomingCall) {
        if (TextUtils.isEmpty(ringtoneUri.getUserInfo()) ||
                incomingCall.getAssociatedUser() == null) {
            return false;
        }

        UserHandle associatedUser = incomingCall.getAssociatedUser();
        if (associatedUser == null) {
            return false;
        }

        String currentUserId = String.valueOf(associatedUser.getIdentifier());
        return currentUserId.equals(ringtoneUri.getUserInfo());
    }

    private AudioAttributes getDefaultRingtoneAudioAttributes(boolean hapticChannelsMuted) {
        return new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)