Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e33238ec authored by Andrei Homescu's avatar Andrei Homescu
Browse files

libbinder: Support unaligned reads/writes in Parcel.cpp

Parcel words have a 4 byte alignment. Calls to readAligned
and writeAligned with larger types, e.g., binder_uintptr_t
from readPointer, would crash with an UBSan violation.
This fixes those crashes by using memcpy() to copy
unaligned values and require that all such values are
trivially copyable.

Bug: 2002930
Test: atest binderRpcTest
Change-Id: Id9430ca85a7d9ae8e9df7328ef7f64fa432233a6
parent 5ad71b55
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -1584,6 +1584,7 @@ status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const
template<class T>
status_t Parcel::readAligned(T *pArg) const {
    static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
    static_assert(std::is_trivially_copyable_v<T>);

    if ((mDataPos+sizeof(T)) <= mDataSize) {
        if (mObjectsSize > 0) {
@@ -1595,9 +1596,8 @@ status_t Parcel::readAligned(T *pArg) const {
            }
        }

        const void* data = mData+mDataPos;
        memcpy(pArg, mData + mDataPos, sizeof(T));
        mDataPos += sizeof(T);
        *pArg =  *reinterpret_cast<const T*>(data);
        return NO_ERROR;
    } else {
        return NOT_ENOUGH_DATA;
@@ -1617,10 +1617,11 @@ T Parcel::readAligned() const {
template<class T>
status_t Parcel::writeAligned(T val) {
    static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
    static_assert(std::is_trivially_copyable_v<T>);

    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
        *reinterpret_cast<T*>(mData+mDataPos) = val;
        memcpy(mData + mDataPos, &val, sizeof(val));
        return finishWrite(sizeof(val));
    }