summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/binder/Status.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index d3520d62e9..352754602f 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -66,13 +66,22 @@ 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();
+ 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.
@@ -95,6 +104,7 @@ status_t Status::readFromParcel(const Parcel& parcel) {
if (mException == EX_SERVICE_SPECIFIC) {
status = parcel.readInt32(&mErrorCode);
}
+
if (status != OK) {
setFromStatusT(status);
return status;