diff options
| author | Steven Moreland <smoreland@google.com> | 2024-10-02 00:37:59 +0000 |
|---|---|---|
| committer | Julian Veit <Claymore1298@gmail.com> | 2025-01-13 08:20:20 +0100 |
| commit | b89a42aa1bb00ecb2f31ad96150ae9870c26d291 (patch) | |
| tree | ef63012ab7588f2d433a2ab1287b2557ad5b59de | |
| parent | 67eb1e61756bb68a6f9027f5ba5935c3a1851266 (diff) | |
libbinder: Parcel: validate read data before write
This is slow, but it's required to prevent memory
corruption.
Ignore-AOSP-First: security
Bug: 370840874
Test: fuzzer
(cherry picked from commit c54dad65317f851ce9d016bd90ec6a7a04da09fc)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:640d942d6a9a26a0beca87d3abdf2ee1048985b9)
Merged-In: Ibc5566ade0389221690dc90324f93394cf7fc9a5
Change-Id: Ibc5566ade0389221690dc90324f93394cf7fc9a5
| -rw-r--r-- | libs/binder/Parcel.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index df6cf9741d..da91900ce9 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1164,6 +1164,10 @@ restart_write: //printf("Writing %ld bytes, padded to %ld\n", len, padded); uint8_t* const data = mData+mDataPos; + if (status_t status = validateReadData(mDataPos + padded); status != OK) { + return nullptr; // drops status + } + // Need to pad at end? if (padded != len) { #if BYTE_ORDER == BIG_ENDIAN @@ -1745,6 +1749,10 @@ status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData) const bool enoughObjects = kernelFields->mObjectsSize < kernelFields->mObjectsCapacity; if (enoughData && enoughObjects) { restart_write: + if (status_t status = validateReadData(mDataPos + sizeof(val)); status != OK) { + return status; + } + *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val; // remember if it's a file descriptor @@ -1988,6 +1996,10 @@ status_t Parcel::writeAligned(T val) { if ((mDataPos+sizeof(val)) <= mDataCapacity) { restart_write: + if (status_t status = validateReadData(mDataPos + sizeof(val)); status != OK) { + return status; + } + memcpy(mData + mDataPos, &val, sizeof(val)); return finishWrite(sizeof(val)); } |
