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

Unverified Commit dca679bf authored by Kevin F. Haggerty's avatar Kevin F. Haggerty
Browse files

Merge tag 'android-security-11.0.0_r74' into staging/lineage-18.1_android-security-11.0.0_r74

Android Security 11.0.0 Release 74 (10993236)

* tag 'android-security-11.0.0_r74':
  RESTRICT AUTOMERGE: Check URI permissions for resumable media artwork
  Updated: always show the keyguard on device lockdown
  Adding in verification of calling UID in onShellCommand
  Revert "On device lockdown, always show the keyguard"
  Validate userId when publishing shortcuts
  Use readUniqueFileDescriptor in incidentd service
  Restrict number of shortcuts can be added through addDynamicShortcuts
  Require permission to unlock keyguard
  Validate URI-based shortcut icon at creation time.
  RESTRICT AUTOMERGE: Drop invalid data.
  Visit Uris related to Notification style extras
  Fix bypass BAL via `requestGeofence`
  Visit Uris added by WearableExtender

Conflicts:
	packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt

Change-Id: I495d0122e69d61e433d4fa5244924c4f6b644fdc
parents c3f27eb7 efa216dc
Loading
Loading
Loading
Loading
+12 −8
Original line number Original line Diff line number Diff line
@@ -500,9 +500,13 @@ status_t IncidentService::onTransact(uint32_t code, const Parcel& data, Parcel*


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

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


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


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


            if (fin != NULL) {
            if (fin != NULL) {
+3 −0
Original line number Original line Diff line number Diff line
@@ -39,4 +39,7 @@ interface IUriGrantsManager {
    void clearGrantedUriPermissions(in String packageName, int userId);
    void clearGrantedUriPermissions(in String packageName, int userId);
    ParceledListSlice getUriPermissions(in String packageName, boolean incoming,
    ParceledListSlice getUriPermissions(in String packageName, boolean incoming,
            boolean persistedOnly);
            boolean persistedOnly);

    int checkGrantUriPermission_ignoreNonSystem(
            int sourceUid, String targetPkg, in Uri uri, int modeFlags, int userId);
}
}
+23 −8
Original line number Original line Diff line number Diff line
@@ -1831,6 +1831,10 @@ public class Notification implements Parcelable
            }
            }
        }
        }


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

        @Override
        @Override
        public Action clone() {
        public Action clone() {
            return new Action(
            return new Action(
@@ -2508,7 +2512,7 @@ public class Notification implements Parcelable


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


@@ -2529,11 +2533,6 @@ public class Notification implements Parcelable
                }
                }
            }
            }


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

            final RemoteInputHistoryItem[] history = getParcelableArrayFromBundle(extras,
            final RemoteInputHistoryItem[] history = getParcelableArrayFromBundle(extras,
                Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class);
                Notification.EXTRA_REMOTE_INPUT_HISTORY_ITEMS, RemoteInputHistoryItem.class);
            if (history != null) {
            if (history != null) {
@@ -2544,9 +2543,14 @@ 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);
            if (person != null && person.getIconUri() != null) {
                visitor.accept(person.getIconUri());
            }
            }


        if (MessagingStyle.class.equals(getNotificationStyle()) && extras != null) {
            final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES);
            final Parcelable[] messages = extras.getParcelableArray(EXTRA_MESSAGES);
            if (!ArrayUtils.isEmpty(messages)) {
            if (!ArrayUtils.isEmpty(messages)) {
                for (MessagingStyle.Message message : MessagingStyle.Message
                for (MessagingStyle.Message message : MessagingStyle.Message
@@ -2579,6 +2583,11 @@ public class Notification implements Parcelable
        if (mBubbleMetadata != null) {
        if (mBubbleMetadata != null) {
            visitIconUri(visitor, mBubbleMetadata.getIcon());
            visitIconUri(visitor, mBubbleMetadata.getIcon());
        }
        }

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


    /**
    /**
@@ -10291,6 +10300,12 @@ public class Notification implements Parcelable
                mFlags &= ~mask;
                mFlags &= ~mask;
            }
            }
        }
        }

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


    /**
    /**
+34 −8
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.FastXmlSerializer;
@@ -45,6 +46,8 @@ import java.util.ArrayList;
 */
 */
public final class PersistableBundle extends BaseBundle implements Cloneable, Parcelable,
public final class PersistableBundle extends BaseBundle implements Cloneable, Parcelable,
        XmlUtils.WriteMapCallback {
        XmlUtils.WriteMapCallback {
    private static final String TAG = "PersistableBundle";

    private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
    private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
    public static final PersistableBundle EMPTY;
    public static final PersistableBundle EMPTY;


@@ -107,7 +110,11 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
     * @hide
     * @hide
     */
     */
    public PersistableBundle(Bundle b) {
    public PersistableBundle(Bundle b) {
        this(b.getMap());
        this(b, true);
    }

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


    /**
    /**
@@ -116,7 +123,7 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
     * @param map a Map containing only those items that can be persisted.
     * @param map a Map containing only those items that can be persisted.
     * @throws IllegalArgumentException if any element of #map cannot 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();
        super();
        mFlags = FLAG_DEFUSABLE;
        mFlags = FLAG_DEFUSABLE;


@@ -125,16 +132,23 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa


        // Now verify each item throwing an exception if there is a violation.
        // Now verify each item throwing an exception if there is a violation.
        final int N = mMap.size();
        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);
            Object value = mMap.valueAt(i);
            if (value instanceof ArrayMap) {
            if (value instanceof ArrayMap) {
                // Fix up any Maps by replacing them with PersistableBundles.
                // 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) {
            } else if (value instanceof Bundle) {
                mMap.setValueAt(i, new PersistableBundle(((Bundle) value)));
                mMap.setValueAt(i, new PersistableBundle((Bundle) value, throwException));
            } else if (!isValidType(value)) {
            } else if (!isValidType(value)) {
                throw new IllegalArgumentException("Bad value in PersistableBundle key="
                final String errorMsg = "Bad value in PersistableBundle key="
                        + mMap.keyAt(i) + " value=" + value);
                        + mMap.keyAt(i) + " value=" + value;
                if (throwException) {
                    throw new IllegalArgumentException(errorMsg);
                } else {
                    Slog.wtfStack(TAG, errorMsg);
                    mMap.removeAt(i);
                }
            }
            }
        }
        }
    }
    }
@@ -249,6 +263,15 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
    /** @hide */
    /** @hide */
    public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
    public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
        unparcel();
        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);
        XmlUtils.writeMapXml(mMap, out, this);
    }
    }


@@ -297,9 +320,12 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
        while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
        while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
                (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
                (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
            if (event == XmlPullParser.START_TAG) {
            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>)
                return new PersistableBundle((ArrayMap<String, Object>)
                        XmlUtils.readThisArrayMapXml(in, startTag, tagName,
                        XmlUtils.readThisArrayMapXml(in, startTag, tagName,
                        new MyReadMapCallback()));
                        new MyReadMapCallback()),
                        /* throwException */ false);
            }
            }
        }
        }
        return EMPTY;
        return EMPTY;
+13 −9
Original line number Original line Diff line number Diff line
@@ -569,6 +569,13 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
            }
            }
        }
        }


        @Override
        public void onStrongAuthStateChanged(int userId) {
            if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
                doKeyguardLocked(null);
            }
        }

        @Override
        @Override
        public void onTrustChanged(int userId) {
        public void onTrustChanged(int userId) {
            if (userId == KeyguardUpdateMonitor.getCurrentUser()) {
            if (userId == KeyguardUpdateMonitor.getCurrentUser()) {
@@ -584,13 +591,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
                notifyHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
                notifyHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
            }
            }
        }
        }

        @Override
        public void onStrongAuthStateChanged(int userId) {
            if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
                doKeyguardLocked(null);
            }
        }
    };
    };


    ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
    ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
@@ -1170,6 +1170,10 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
            mExternallyEnabled = enabled;
            mExternallyEnabled = enabled;


            if (!enabled && mShowing) {
            if (!enabled && mShowing) {
                if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
                    Log.d(TAG, "keyguardEnabled(false) overridden by user lockdown");
                    return;
                }
                if (mExitSecureCallback != null) {
                if (mExitSecureCallback != null) {
                    if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring");
                    if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring");
                    // we're in the process of handling a request to verify the user
                    // we're in the process of handling a request to verify the user
@@ -1406,7 +1410,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
            return;
            return;
        }
        }


        // if another app is disabling us, don't show
        // if another app is disabling us, don't show unless we're in lockdown mode
        if (!mExternallyEnabled
        if (!mExternallyEnabled
                && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
                && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) {
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
Loading