diff options
| author | 2022-07-09 08:29:46 +0000 | |
|---|---|---|
| committer | 2022-07-09 08:29:46 +0000 | |
| commit | 4840d1e7fdea832291fb64737cd61a65bb23a77d (patch) | |
| tree | 5239f4d130c62359afdfd7ea618859fbd09c180b | |
| parent | e43e5bea0f207f4354f8ec86e147ffe639f80d6d (diff) | |
| parent | f2532967f521b8c6e7083c88ccde04af2f045736 (diff) | |
Merge "libbinder: Allow vector construction from unaligned data." am: f2532967f5
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2087849
Change-Id: Id2028b28e9ff153ccb571a46b557ed14f886ad77
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
| -rw-r--r-- | libs/binder/include/binder/Parcel.h | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 32b0ded55c..91febbd7bb 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -1184,10 +1184,20 @@ private: c->clear(); // must clear before resizing/reserving otherwise move ctors may be called. if constexpr (is_pointer_equivalent_array_v<T>) { // could consider POD without gaps and alignment of 4. - auto data = reinterpret_cast<const T*>( - readInplace(static_cast<size_t>(size) * sizeof(T))); + size_t dataLen; + if (__builtin_mul_overflow(size, sizeof(T), &dataLen)) { + return -EOVERFLOW; + } + auto data = reinterpret_cast<const T*>(readInplace(dataLen)); if (data == nullptr) return BAD_VALUE; - c->insert(c->begin(), data, data + size); // insert should do a reserve(). + // std::vector::insert and similar methods will require type-dependent + // byte alignment when inserting from a const iterator such as `data`, + // e.g. 8 byte alignment for int64_t, and so will not work if `data` + // is 4 byte aligned (which is all Parcel guarantees). Copying + // the contents into the vector directly, where possible, circumvents + // this. + c->resize(size); + memcpy(c->data(), data, dataLen); } else if constexpr (std::is_same_v<T, bool> || std::is_same_v<T, char16_t>) { c->reserve(size); // avoids default initialization |