OSDN Git Service

[RESTRICT AUTOMERGE] libbinder: Status: check dataPosition sets.
authorSteven Moreland <smoreland@google.com>
Mon, 20 May 2019 22:28:13 +0000 (15:28 -0700)
committerNikoli Cartagena <dargeren@google.com>
Mon, 10 Jun 2019 21:06:51 +0000 (14:06 -0700)
Bug: 132650049
Test: fuzzer
Change-Id: Id230eae4316a444bc82b416b2049d5a5f589f89a
(cherry picked from commit 00d4358fcd2875b1e26ac50d620f2dec439ef3ee)

libs/binder/Status.cpp

index 006f7f9..8b9dee8 100644 (file)
@@ -76,13 +76,23 @@ status_t Status::readFromParcel(const Parcel& parcel) {
     // Skip over fat response headers.  Not used (or propagated) in native code.
     if (mException == EX_HAS_REPLY_HEADER) {
         // Note that the header size includes the 4 byte size field.
-        const int32_t header_start = parcel.dataPosition();
+        const size_t header_start = parcel.dataPosition();
+        // Get available size before reading more
+        const size_t header_avail = parcel.dataAvail();
+
         int32_t header_size;
         status = parcel.readInt32(&header_size);
         if (status != OK) {
             setFromStatusT(status);
             return status;
         }
+
+        if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) {
+            android_errorWriteLog(0x534e4554, "132650049");
+            setFromStatusT(UNKNOWN_ERROR);
+            return UNKNOWN_ERROR;
+        }
+
         parcel.setDataPosition(header_start + header_size);
         // And fat response headers are currently only used when there are no
         // exceptions, so act like there was no error.
@@ -106,13 +116,23 @@ status_t Status::readFromParcel(const Parcel& parcel) {
         status = parcel.readInt32(&mErrorCode);
     } else if (mException == EX_PARCELABLE) {
         // Skip over the blob of Parcelable data
-        const int32_t header_start = parcel.dataPosition();
+        const size_t header_start = parcel.dataPosition();
+        // Get available size before reading more
+        const size_t header_avail = parcel.dataAvail();
+
         int32_t header_size;
         status = parcel.readInt32(&header_size);
         if (status != OK) {
             setFromStatusT(status);
             return status;
         }
+
+        if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) {
+            android_errorWriteLog(0x534e4554, "132650049");
+            setFromStatusT(UNKNOWN_ERROR);
+            return UNKNOWN_ERROR;
+        }
+
         parcel.setDataPosition(header_start + header_size);
     }
     if (status != OK) {