libbinder: Allow vector construction from unaligned data.

std::vector::insert(const_iterator pos, ...) requires that
`pos` be aligned to the size of the type it points to, e.g.
8 byte aligned for an int64_t iterator, to avoid undefined
behavior. In cases where the type is trivially copyable,
it is safe to memcpy the contents of the buffer directly
into the vector. This change does not cover non-trivially-copyable
types that are not aligned to their size within `data`.

Bug: None
Test: run AIDL client / server tests
Change-Id: Ie1a44659e79f7a07cf6c3b318870d0279e1516ce
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 32b0ded..91febbd 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -1184,10 +1184,20 @@
         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