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
diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h
index 09d2ad8..87c32a6 100644
--- a/include/media/stagefright/foundation/AMessage.h
+++ b/include/media/stagefright/foundation/AMessage.h
@@ -62,7 +62,29 @@
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);
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 06abd8d..1b3b3eb 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -75,6 +75,8 @@
}
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 @@
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);
}
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 855ac95..37fb33f 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -595,7 +595,7 @@
}
// 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 @@
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 @@
default:
{
ALOGE("This type of object cannot cross process boundaries.");
- TRESPASS();
+ return NULL;
}
}