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

Commit 8dab1730 authored by Pawin Vongmasa's avatar Pawin Vongmasa
Browse files

AMessage::FromParcel(): Limit recursion depth; report NULL on failure.

- FromParcel() now takes as an optional parameter the maximum recursion depth.
  (The default value is currently set to 255.) On the event that the input
  parcel has AMessage nested deeper than the maximum recursion depth,
  FromParcel() will return NULL.
- Also, when the input parcel has items that are not recognized by FromParcel(),
  NULL will be returned. (The old behavior was to invoke TRESPASS, which would
  cause the process to stop.)

Bug: 28332724
Change-Id: I722097f7d1711668f197651d7e8135d703f6c91f
parent 0b667e2f
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -62,7 +62,29 @@ struct AMessage : public RefBase {
    AMessage();
    AMessage(uint32_t what, const sp<const AHandler> &handler);

    static sp<AMessage> FromParcel(const Parcel &parcel);
    // Construct an AMessage from a parcel.
    // nestingAllowed determines how many levels AMessage can be nested inside
    // AMessage. The default value here is arbitrarily set to 255.
    // FromParcel() returns NULL on error, which occurs when the input parcel
    // contains
    // - an AMessage nested deeper than maxNestingLevel; or
    // - an item whose type is not recognized by this function.
    // Types currently recognized by this function are:
    //   Item types      set/find function suffixes
    //   ==========================================
    //     int32_t                Int32
    //     int64_t                Int64
    //     size_t                 Size
    //     float                  Float
    //     double                 Double
    //     AString                String
    //     AMessage               Message
    static sp<AMessage> FromParcel(const Parcel &parcel,
                                   size_t maxNestingLevel = 255);

    // Write this AMessage to a parcel.
    // All items in the AMessage must have types that are recognized by
    // FromParcel(); otherwise, TRESPASS error will occur.
    void writeToParcel(Parcel *parcel) const;

    void setWhat(uint32_t what);
+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ sp<MediaCodecInfo::Capabilities> MediaCodecInfo::Capabilities::FromParcel(
    }
    uint32_t flags = static_cast<uint32_t>(parcel.readInt32());
    sp<AMessage> details = AMessage::FromParcel(parcel);
    if (details == NULL)
        return NULL;
    if (caps != NULL) {
        caps->mFlags = flags;
        caps->mDetails = details;
@@ -163,6 +165,8 @@ sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
    for (size_t i = 0; i < size; i++) {
        AString mime = AString::FromParcel(parcel);
        sp<Capabilities> caps = Capabilities::FromParcel(parcel);
        if (caps == NULL)
            return NULL;
        if (info != NULL) {
            info->mCaps.add(mime, caps);
        }
+15 −3
Original line number Diff line number Diff line
@@ -595,7 +595,7 @@ AString AMessage::debugString(int32_t indent) const {
}

// static
sp<AMessage> AMessage::FromParcel(const Parcel &parcel) {
sp<AMessage> AMessage::FromParcel(const Parcel &parcel, size_t maxNestingLevel) {
    int32_t what = parcel.readInt32();
    sp<AMessage> msg = new AMessage();
    msg->setWhat(what);
@@ -667,7 +667,19 @@ sp<AMessage> AMessage::FromParcel(const Parcel &parcel) {

            case kTypeMessage:
            {
                sp<AMessage> subMsg = AMessage::FromParcel(parcel);
                if (maxNestingLevel == 0) {
                    ALOGE("Too many levels of AMessage nesting.");
                    return NULL;
                }
                sp<AMessage> subMsg = AMessage::FromParcel(
                        parcel,
                        maxNestingLevel - 1);
                if (subMsg == NULL) {
                    // This condition will be triggered when there exists an
                    // object that cannot cross process boundaries or when the
                    // level of nested AMessage is too deep.
                    return NULL;
                }
                subMsg->incStrong(msg.get());

                item->u.refValue = subMsg.get();
@@ -677,7 +689,7 @@ sp<AMessage> AMessage::FromParcel(const Parcel &parcel) {
            default:
            {
                ALOGE("This type of object cannot cross process boundaries.");
                TRESPASS();
                return NULL;
            }
        }