Loading cmds/incidentd/src/IncidentService.cpp +12 −8 Original line number Diff line number Diff line Loading @@ -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++) { Loading @@ -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) { Loading core/java/android/app/IActivityTaskManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/android/app/IUriGrantsManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -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); } core/java/android/app/Notification.java +33 −16 Original line number Diff line number Diff line Loading @@ -2138,6 +2138,10 @@ public class Notification implements Parcelable } } private void visitUris(@NonNull Consumer<Uri> visitor) { visitIconUri(visitor, getIcon()); } @Override public Action clone() { return new Action( Loading Loading @@ -2823,7 +2827,7 @@ public class Notification implements Parcelable if (actions != null) { for (Action action : actions) { visitIconUri(visitor, action.getIcon()); action.visitUris(visitor); } } Loading @@ -2846,18 +2850,14 @@ public class Notification implements Parcelable 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); Loading @@ -2869,10 +2869,16 @@ public class Notification implements Parcelable } } } // 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()); } if (isStyle(MessagingStyle.class) && extras != null) { final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES); final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES, Parcelable.class); if (!ArrayUtils.isEmpty(messages)) { for (MessagingStyle.Message message : MessagingStyle.Message .getMessagesFromBundleArray(messages)) { Loading @@ -2885,7 +2891,8 @@ public class Notification implements Parcelable } } 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)) { Loading @@ -2898,20 +2905,24 @@ public class Notification implements Parcelable } } 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); } } /** Loading Loading @@ -11630,6 +11641,12 @@ public class Notification implements Parcelable mFlags &= ~mask; } } private void visitUris(@NonNull Consumer<Uri> visitor) { for (Action action : mActions) { action.visitUris(visitor); } } } /** Loading core/java/android/os/PersistableBundle.java +34 −8 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; 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; Loading Loading @@ -50,6 +51,8 @@ import java.util.ArrayList; */ 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}. */ Loading Loading @@ -118,7 +121,11 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa * @hide */ public PersistableBundle(Bundle b) { this(b.getItemwiseMap()); this(b, true); } private PersistableBundle(Bundle b, boolean throwException) { this(b.getItemwiseMap(), throwException); } /** Loading @@ -127,7 +134,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa * @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; Loading @@ -136,16 +143,23 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa // 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); } } } } Loading Loading @@ -268,6 +282,15 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa /** @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); } Loading Loading @@ -322,9 +345,12 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa 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 Loading Loading
cmds/incidentd/src/IncidentService.cpp +12 −8 Original line number Diff line number Diff line Loading @@ -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++) { Loading @@ -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) { Loading
core/java/android/app/IActivityTaskManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/android/app/IUriGrantsManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -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); }
core/java/android/app/Notification.java +33 −16 Original line number Diff line number Diff line Loading @@ -2138,6 +2138,10 @@ public class Notification implements Parcelable } } private void visitUris(@NonNull Consumer<Uri> visitor) { visitIconUri(visitor, getIcon()); } @Override public Action clone() { return new Action( Loading Loading @@ -2823,7 +2827,7 @@ public class Notification implements Parcelable if (actions != null) { for (Action action : actions) { visitIconUri(visitor, action.getIcon()); action.visitUris(visitor); } } Loading @@ -2846,18 +2850,14 @@ public class Notification implements Parcelable 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); Loading @@ -2869,10 +2869,16 @@ public class Notification implements Parcelable } } } // 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()); } if (isStyle(MessagingStyle.class) && extras != null) { final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES); final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES, Parcelable.class); if (!ArrayUtils.isEmpty(messages)) { for (MessagingStyle.Message message : MessagingStyle.Message .getMessagesFromBundleArray(messages)) { Loading @@ -2885,7 +2891,8 @@ public class Notification implements Parcelable } } 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)) { Loading @@ -2898,20 +2905,24 @@ public class Notification implements Parcelable } } 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); } } /** Loading Loading @@ -11630,6 +11641,12 @@ public class Notification implements Parcelable mFlags &= ~mask; } } private void visitUris(@NonNull Consumer<Uri> visitor) { for (Action action : mActions) { action.visitUris(visitor); } } } /** Loading
core/java/android/os/PersistableBundle.java +34 −8 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; 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; Loading Loading @@ -50,6 +51,8 @@ import java.util.ArrayList; */ 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}. */ Loading Loading @@ -118,7 +121,11 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa * @hide */ public PersistableBundle(Bundle b) { this(b.getItemwiseMap()); this(b, true); } private PersistableBundle(Bundle b, boolean throwException) { this(b.getItemwiseMap(), throwException); } /** Loading @@ -127,7 +134,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa * @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; Loading @@ -136,16 +143,23 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa // 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); } } } } Loading Loading @@ -268,6 +282,15 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa /** @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); } Loading Loading @@ -322,9 +345,12 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa 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 Loading