[RESTRICT AUTOMERGE] libbinder: Status: check dataPosition sets.
Bug: 132650049
Test: fuzzer
Change-Id: Id230eae4316a444bc82b416b2049d5a5f589f89a
(cherry picked from commit 00d4358fcd2875b1e26ac50d620f2dec439ef3ee)
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index 006f7f9..8b9dee8 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -76,13 +76,23 @@
// 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 = 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) {