mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-14 18:34:30 -05:00
142 lines
5.9 KiB
Diff
142 lines
5.9 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Michael Mikhail <michaelmikhil@google.com>
|
||
|
Date: Fri, 28 Apr 2023 16:17:16 +0000
|
||
|
Subject: [PATCH] Verify URI permissions in MediaMetadata
|
||
|
|
||
|
Add a check for URI permission to make sure that user can access the URI
|
||
|
set in MediaMetadata. If permission is denied, clear the URI string set
|
||
|
in metadata.
|
||
|
|
||
|
Bug: 271851153
|
||
|
Test: atest MediaSessionTest
|
||
|
Test: Verified by POC app attached in bug, image of second user is not
|
||
|
the UMO background of the first user.
|
||
|
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f95b7fc61d6b3bf49420ded0357bec031f8cbdcf)
|
||
|
Merged-In: I384f8e230c909d8fc8e5f147e2fd3558fec44626
|
||
|
Change-Id: I384f8e230c909d8fc8e5f147e2fd3558fec44626
|
||
|
---
|
||
|
.../server/media/MediaSessionRecord.java | 63 ++++++++++++++++---
|
||
|
1 file changed, 54 insertions(+), 9 deletions(-)
|
||
|
|
||
|
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
|
||
|
index b65e74d219cb..1c68b95517f1 100644
|
||
|
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
|
||
|
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
|
||
|
@@ -16,7 +16,12 @@
|
||
|
|
||
|
package com.android.server.media;
|
||
|
|
||
|
+import android.app.ActivityManager;
|
||
|
+import android.app.ActivityManagerNative;
|
||
|
+import android.app.IActivityManager;
|
||
|
import android.app.PendingIntent;
|
||
|
+import android.content.ContentProvider;
|
||
|
+import android.content.ContentResolver;
|
||
|
import android.content.Context;
|
||
|
import android.content.Intent;
|
||
|
import android.content.pm.ParceledListSlice;
|
||
|
@@ -48,6 +53,7 @@ import android.os.Message;
|
||
|
import android.os.RemoteException;
|
||
|
import android.os.ResultReceiver;
|
||
|
import android.os.SystemClock;
|
||
|
+import android.text.TextUtils;
|
||
|
import android.util.Log;
|
||
|
import android.util.Slog;
|
||
|
import android.view.KeyEvent;
|
||
|
@@ -63,6 +69,10 @@ import java.util.ArrayList;
|
||
|
*/
|
||
|
public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||
|
private static final String TAG = "MediaSessionRecord";
|
||
|
+ private static final String[] ART_URIS = new String[] {
|
||
|
+ MediaMetadata.METADATA_KEY_ALBUM_ART_URI,
|
||
|
+ MediaMetadata.METADATA_KEY_ART_URI,
|
||
|
+ MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI};
|
||
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||
|
|
||
|
/**
|
||
|
@@ -90,6 +100,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||
|
private final SessionStub mSession;
|
||
|
private final SessionCb mSessionCb;
|
||
|
private final MediaSessionService mService;
|
||
|
+ final IActivityManager mAm;
|
||
|
|
||
|
private final Object mLock = new Object();
|
||
|
private final ArrayList<ISessionControllerCallback> mControllerCallbacks =
|
||
|
@@ -145,6 +156,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||
|
mAudioManager = (AudioManager) service.getContext().getSystemService(Context.AUDIO_SERVICE);
|
||
|
mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
|
||
|
mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
|
||
|
+ mAm = ActivityManagerNative.getDefault();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
@@ -211,6 +223,15 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||
|
return (mFlags & flag) != 0;
|
||
|
}
|
||
|
|
||
|
+ /**
|
||
|
+ * Get the UID this session was created for.
|
||
|
+ *
|
||
|
+ * @return The UID for this session.
|
||
|
+ */
|
||
|
+ public int getUid() {
|
||
|
+ return mOwnerUid;
|
||
|
+ }
|
||
|
+
|
||
|
/**
|
||
|
* Get the user id this session was created for.
|
||
|
*
|
||
|
@@ -856,19 +877,43 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
|
||
|
@Override
|
||
|
public void setMetadata(MediaMetadata metadata) {
|
||
|
synchronized (mLock) {
|
||
|
- MediaMetadata temp = metadata == null ? null : new MediaMetadata.Builder(metadata)
|
||
|
- .build();
|
||
|
- // This is to guarantee that the underlying bundle is unparceled
|
||
|
- // before we set it to prevent concurrent reads from throwing an
|
||
|
- // exception
|
||
|
- if (temp != null) {
|
||
|
- temp.size();
|
||
|
- }
|
||
|
- mMetadata = temp;
|
||
|
+ mMetadata = sanitizeMediaMetadata(metadata);
|
||
|
}
|
||
|
mHandler.post(MessageHandler.MSG_UPDATE_METADATA);
|
||
|
}
|
||
|
|
||
|
+ private MediaMetadata sanitizeMediaMetadata(MediaMetadata metadata) {
|
||
|
+ if (metadata == null) {
|
||
|
+ return null;
|
||
|
+ }
|
||
|
+ MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder(metadata);
|
||
|
+ for (String key: ART_URIS) {
|
||
|
+ String uriString = metadata.getString(key);
|
||
|
+ if (TextUtils.isEmpty(uriString)) {
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ Uri uri = Uri.parse(uriString);
|
||
|
+ if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ try {
|
||
|
+ mAm.checkGrantUriPermission(getUid(),
|
||
|
+ getPackageName(),
|
||
|
+ ContentProvider.getUriWithoutUserId(uri),
|
||
|
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
|
||
|
+ ContentProvider.getUserIdFromUri(uri, getUserId()));
|
||
|
+ } catch (RemoteException | SecurityException e) {
|
||
|
+ metadataBuilder.putString(key, null);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ MediaMetadata sanitizedMetadata = metadataBuilder.build();
|
||
|
+ // sanitizedMetadata.size() guarantees that the underlying bundle is unparceled
|
||
|
+ // before we set it to prevent concurrent reads from throwing an
|
||
|
+ // exception
|
||
|
+ sanitizedMetadata.size();
|
||
|
+ return sanitizedMetadata;
|
||
|
+ }
|
||
|
+
|
||
|
@Override
|
||
|
public void setPlaybackState(PlaybackState state) {
|
||
|
int oldState = mPlaybackState == null ? 0 : mPlaybackState.getState();
|