Skip to content

Commit

Permalink
Merge tag 'android-security-13.0.0_r12' into HEAD
Browse files Browse the repository at this point in the history
Android Security 13.0.0 Release 12 (10993242)

Change-Id: Iaf21efabd7ccb6da55814a1704c318bb066ff1d1
  • Loading branch information
Myself5 committed Dec 8, 2023
2 parents 1eaf969 + d203ccf commit 95aedd0
Show file tree
Hide file tree
Showing 20 changed files with 349 additions and 43 deletions.
20 changes: 12 additions & 8 deletions cmds/incidentd/src/IncidentService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,13 @@ status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel*

switch (code) {
case SHELL_COMMAND_TRANSACTION: {
int in = data.readFileDescriptor();
int out = data.readFileDescriptor();
int err = data.readFileDescriptor();
unique_fd in, out, err;
if (status_t status = data.readUniqueFileDescriptor(&in); status != OK) return status;

if (status_t status = data.readUniqueFileDescriptor(&out); status != OK) return status;

if (status_t status = data.readUniqueFileDescriptor(&err); status != OK) return status;

int argc = data.readInt32();
Vector<String8> args;
for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
Expand All @@ -512,15 +516,15 @@ status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel*
sp<IResultReceiver> resultReceiver =
IResultReceiver::asInterface(data.readStrongBinder());

FILE* fin = fdopen(in, "r");
FILE* fout = fdopen(out, "w");
FILE* ferr = fdopen(err, "w");
FILE* fin = fdopen(in.release(), "r");
FILE* fout = fdopen(out.release(), "w");
FILE* ferr = fdopen(err.release(), "w");

if (fin == NULL || fout == NULL || ferr == NULL) {
resultReceiver->send(NO_MEMORY);
} else {
err = command(fin, fout, ferr, args);
resultReceiver->send(err);
status_t result = command(fin, fout, ferr, args);
resultReceiver->send(result);
}

if (fin != NULL) {
Expand Down
1 change: 1 addition & 0 deletions core/java/android/app/IActivityTaskManager.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ interface IActivityTaskManager {
* {@link android.view.WindowManagerPolicyConstants#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
* etc.
*/
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD)")
void keyguardGoingAway(int flags);

void suppressResizeConfigChanges(boolean suppress);
Expand Down
3 changes: 3 additions & 0 deletions core/java/android/app/IUriGrantsManager.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@ interface IUriGrantsManager {
void clearGrantedUriPermissions(in String packageName, int userId);
ParceledListSlice getUriPermissions(in String packageName, boolean incoming,
boolean persistedOnly);

int checkGrantUriPermission_ignoreNonSystem(
int sourceUid, String targetPkg, in Uri uri, int modeFlags, int userId);
}
49 changes: 33 additions & 16 deletions core/java/android/app/Notification.java
Original file line number Diff line number Diff line change
Expand Up @@ -2138,6 +2138,10 @@ public Action build() {
}
}

private void visitUris(@NonNull Consumer<Uri> visitor) {
visitIconUri(visitor, getIcon());
}

@Override
public Action clone() {
return new Action(
Expand Down Expand Up @@ -2823,7 +2827,7 @@ public void visitUris(@NonNull Consumer<Uri> visitor) {

if (actions != null) {
for (Action action : actions) {
visitIconUri(visitor, action.getIcon());
action.visitUris(visitor);
}
}

Expand All @@ -2846,18 +2850,14 @@ public void visitUris(@NonNull Consumer<Uri> visitor) {
visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI)));
}

ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST);
ArrayList<Person> people = extras.getParcelableArrayList(EXTRA_PEOPLE_LIST,
Person.class);
if (people != null && !people.isEmpty()) {
for (Person p : people) {
visitor.accept(p.getIconUri());
}
}

final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
if (person != null) {
visitor.accept(person.getIconUri());
}

final RemoteInputHistoryItem[] history = extras.getParcelableArray(
Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS,
RemoteInputHistoryItem.class);
Expand All @@ -2869,10 +2869,16 @@ public void visitUris(@NonNull Consumer<Uri> visitor) {
}
}
}
}

if (isStyle(MessagingStyle.class) && extras != null) {
final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES);
// Extras for MessagingStyle. We visit them even if not isStyle(MessagingStyle), since
// Notification Listeners might use directly (without the isStyle check).
final Person person = extras.getParcelable(EXTRA_MESSAGING_PERSON, Person.class);
if (person != null) {
visitor.accept(person.getIconUri());
}

final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES,
Parcelable.class);
if (!ArrayUtils.isEmpty(messages)) {
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(messages)) {
Expand All @@ -2885,7 +2891,8 @@ public void visitUris(@NonNull Consumer<Uri> visitor) {
}
}

final Parcelable[] historic = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES);
final Parcelable[] historic = extras.getParcelableArray(EXTRA_HISTORIC_MESSAGES,
Parcelable.class);
if (!ArrayUtils.isEmpty(historic)) {
for (MessagingStyle.Message message : MessagingStyle.Message
.getMessagesFromBundleArray(historic)) {
Expand All @@ -2898,20 +2905,24 @@ public void visitUris(@NonNull Consumer<Uri> visitor) {
}
}

visitIconUri(visitor, extras.getParcelable(EXTRA_CONVERSATION_ICON));
}
visitIconUri(visitor, extras.getParcelable(EXTRA_CONVERSATION_ICON, Icon.class));

if (isStyle(CallStyle.class) & extras != null) {
Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON);
// Extras for CallStyle (same reason for visiting without checking isStyle).
Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON, Person.class);
if (callPerson != null) {
visitor.accept(callPerson.getIconUri());
}
visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON));
visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON, Icon.class));
}

if (mBubbleMetadata != null) {
visitIconUri(visitor, mBubbleMetadata.getIcon());
}

if (extras != null && extras.containsKey(WearableExtender.EXTRA_WEARABLE_EXTENSIONS)) {
WearableExtender extender = new WearableExtender(this);
extender.visitUris(visitor);
}
}

/**
Expand Down Expand Up @@ -11630,6 +11641,12 @@ private void setFlag(int mask, boolean value) {
mFlags &= ~mask;
}
}

private void visitUris(@NonNull Consumer<Uri> visitor) {
for (Action action : mActions) {
action.visitUris(visitor);
}
}
}

/**
Expand Down
42 changes: 34 additions & 8 deletions core/java/android/os/PersistableBundle.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.Slog;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
Expand Down Expand Up @@ -50,6 +51,8 @@
*/
public final class PersistableBundle extends BaseBundle implements Cloneable, Parcelable,
XmlUtils.WriteMapCallback {
private static final String TAG = "PersistableBundle";

private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";

/** An unmodifiable {@code PersistableBundle} that is always {@link #isEmpty() empty}. */
Expand Down Expand Up @@ -118,7 +121,11 @@ public PersistableBundle(PersistableBundle b) {
* @hide
*/
public PersistableBundle(Bundle b) {
this(b.getItemwiseMap());
this(b, true);
}

private PersistableBundle(Bundle b, boolean throwException) {
this(b.getItemwiseMap(), throwException);
}

/**
Expand All @@ -127,7 +134,7 @@ public PersistableBundle(Bundle b) {
* @param map a Map containing only those items that can be persisted.
* @throws IllegalArgumentException if any element of #map cannot be persisted.
*/
private PersistableBundle(ArrayMap<String, Object> map) {
private PersistableBundle(ArrayMap<String, Object> map, boolean throwException) {
super();
mFlags = FLAG_DEFUSABLE;

Expand All @@ -136,16 +143,23 @@ private PersistableBundle(ArrayMap<String, Object> map) {

// Now verify each item throwing an exception if there is a violation.
final int N = mMap.size();
for (int i=0; i<N; i++) {
for (int i = N - 1; i >= 0; --i) {
Object value = mMap.valueAt(i);
if (value instanceof ArrayMap) {
// Fix up any Maps by replacing them with PersistableBundles.
mMap.setValueAt(i, new PersistableBundle((ArrayMap<String, Object>) value));
mMap.setValueAt(i,
new PersistableBundle((ArrayMap<String, Object>) value, throwException));
} else if (value instanceof Bundle) {
mMap.setValueAt(i, new PersistableBundle(((Bundle) value)));
mMap.setValueAt(i, new PersistableBundle((Bundle) value, throwException));
} else if (!isValidType(value)) {
throw new IllegalArgumentException("Bad value in PersistableBundle key="
+ mMap.keyAt(i) + " value=" + value);
final String errorMsg = "Bad value in PersistableBundle key="
+ mMap.keyAt(i) + " value=" + value;
if (throwException) {
throw new IllegalArgumentException(errorMsg);
} else {
Slog.wtfStack(TAG, errorMsg);
mMap.removeAt(i);
}
}
}
}
Expand Down Expand Up @@ -268,6 +282,15 @@ public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserExcept
/** @hide */
public void saveToXml(TypedXmlSerializer out) throws IOException, XmlPullParserException {
unparcel();
// Explicitly drop invalid types an attacker may have added before persisting.
for (int i = mMap.size() - 1; i >= 0; --i) {
final Object value = mMap.valueAt(i);
if (!isValidType(value)) {
Slog.e(TAG, "Dropping bad data before persisting: "
+ mMap.keyAt(i) + "=" + value);
mMap.removeAt(i);
}
}
XmlUtils.writeMapXml(mMap, out, this);
}

Expand Down Expand Up @@ -322,9 +345,12 @@ public static PersistableBundle restoreFromXml(TypedXmlPullParser in) throws IOE
while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
(event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
if (event == XmlPullParser.START_TAG) {
// Don't throw an exception when restoring from XML since an attacker could try to
// input invalid data in the persisted file.
return new PersistableBundle((ArrayMap<String, Object>)
XmlUtils.readThisArrayMapXml(in, startTag, tagName,
new MyReadMapCallback()));
new MyReadMapCallback()),
/* throwException */ false);
}
}
return new PersistableBundle(); // An empty mutable PersistableBundle
Expand Down
4 changes: 2 additions & 2 deletions core/java/com/android/internal/app/IAppOpsService.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ interface IAppOpsService {
int checkAudioOperation(int code, int usage, int uid, String packageName);
boolean shouldCollectNotes(int opCode);
void setCameraAudioRestriction(int mode);
void startWatchingModeWithFlags(int op, String packageName, int flags,
IAppOpsCallback callback);
// End of methods also called by native code.
// Any new method exposed to native must be added after the last one, do not reorder

Expand Down Expand Up @@ -110,8 +112,6 @@ interface IAppOpsService {
void startWatchingStarted(in int[] ops, IAppOpsStartedCallback callback);
void stopWatchingStarted(IAppOpsStartedCallback callback);

void startWatchingModeWithFlags(int op, String packageName, int flags, IAppOpsCallback callback);

void startWatchingNoted(in int[] ops, IAppOpsNotedCallback callback);
void stopWatchingNoted(IAppOpsNotedCallback callback);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1933,8 +1933,7 @@ private void updateInputRestrictedLocked() {
*/
private void doKeyguardLocked(Bundle options) {
// if another app is disabling us, don't show
if (!mExternallyEnabled
&& !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
if (!mExternallyEnabled) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");

mNeedToReshowWhenReenabled = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ package com.android.systemui.media.controls.pipeline
import android.app.Notification
import android.app.Notification.EXTRA_SUBSTITUTE_APP_NAME
import android.app.PendingIntent
import android.app.UriGrantsManager
import android.app.smartspace.SmartspaceConfig
import android.app.smartspace.SmartspaceManager
import android.app.smartspace.SmartspaceSession
import android.app.smartspace.SmartspaceTarget
import android.content.BroadcastReceiver
import android.content.ContentProvider
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
Expand Down Expand Up @@ -677,10 +679,13 @@ class MediaDataManager(
Log.d(TAG, "adding track for $userId from browser: $desc")
}

val currentEntry = mediaEntries.get(packageName)
val appUid = currentEntry?.appUid ?: Process.INVALID_UID

// Album art
var artworkBitmap = desc.iconBitmap
if (artworkBitmap == null && desc.iconUri != null) {
artworkBitmap = loadBitmapFromUri(desc.iconUri!!)
artworkBitmap = loadBitmapFromUriForUser(desc.iconUri!!, userId, appUid, packageName)
}
val artworkIcon =
if (artworkBitmap != null) {
Expand All @@ -689,9 +694,7 @@ class MediaDataManager(
null
}

val currentEntry = mediaEntries.get(packageName)
val instanceId = currentEntry?.instanceId ?: logger.getNewInstanceId()
val appUid = currentEntry?.appUid ?: Process.INVALID_UID
val isExplicit =
desc.extras?.getLong(MediaConstants.METADATA_KEY_IS_EXPLICIT) ==
MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT &&
Expand Down Expand Up @@ -1231,6 +1234,30 @@ class MediaDataManager(
false
}
}

/** Returns a bitmap if the user can access the given URI, else null */
private fun loadBitmapFromUriForUser(
uri: Uri,
userId: Int,
appUid: Int,
packageName: String,
): Bitmap? {
try {
val ugm = UriGrantsManager.getService()
ugm.checkGrantUriPermission_ignoreNonSystem(
appUid,
packageName,
ContentProvider.getUriWithoutUserId(uri),
Intent.FLAG_GRANT_READ_URI_PERMISSION,
ContentProvider.getUserIdFromUri(uri, userId)
)
return loadBitmapFromUri(uri)
} catch (e: SecurityException) {
Log.e(TAG, "Failed to get URI permission: $e")
}
return null
}

/**
* Load a bitmap from a URI
*
Expand Down
Loading

0 comments on commit 95aedd0

Please sign in to comment.