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

Commit 1fda67b0 authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder: ensure entire Parcel is the same format

Extra check in preparation for versioning work/as a guard against misuse
of this API. Note - these functions are very much like constructors, but
they can't be because Parcel is that errorprone type of object which
resets its internal state (for better or worse).

Bug: 182938972
Test: binderRpcTest
Change-Id: Ibdbe8161db9d0c8fba86f1c691c73aab49b21bc0
parent 438cce8a
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -555,12 +555,17 @@ void Parcel::markSensitive() const
}

void Parcel::markForBinder(const sp<IBinder>& binder) {
    LOG_ALWAYS_FATAL_IF(mData != nullptr, "format must be set before data is written");

    if (binder && binder->remoteBinder() && binder->remoteBinder()->isRpcBinder()) {
        markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcConnection());
    }
}

void Parcel::markForRpc(const sp<RpcConnection>& connection) {
    LOG_ALWAYS_FATAL_IF(mData != nullptr && mOwner == nullptr,
                        "format must be set before data is written OR on IPC data");

    LOG_ALWAYS_FATAL_IF(connection == nullptr, "markForRpc requires connection");
    mConnection = connection;
}
+4 −4
Original line number Diff line number Diff line
@@ -101,10 +101,6 @@ public:
    // is for an RPC transaction).
    void markForBinder(const sp<IBinder>& binder);

    // Whenever possible, markForBinder should be preferred. This method is
    // called automatically on reply Parcels for RPC transactions.
    void markForRpc(const sp<RpcConnection>& connection);

    // Whether this Parcel is written for RPC transactions (after calls to
    // markForBinder or markForRpc).
    bool isForRpc() const;
@@ -540,6 +536,10 @@ private:
                                            const binder_size_t* objects, size_t objectsCount,
                                            release_func relFunc);

    // Whenever possible, markForBinder should be preferred. This method is
    // called automatically on reply Parcels for RPC transactions.
    void markForRpc(const sp<RpcConnection>& connection);

    status_t            finishWrite(size_t len);
    void                releaseObjects();
    void                acquireObjects();
+1 −0
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ public:
    };

private:
    friend sp<RpcConnection>;
    RpcConnection();

    bool addServer(const SocketAddress& address);
+2 −0
Original line number Diff line number Diff line
@@ -598,6 +598,8 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) {
    }

    *in = new AParcel(binder);
    (*in)->get()->markForBinder(binder->getBinder());

    status_t status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor());
    binder_status_t ret = PruneStatusT(status);

+1 −5
Original line number Diff line number Diff line
@@ -29,11 +29,7 @@ struct AParcel {

    explicit AParcel(AIBinder* binder) : AParcel(binder, new ::android::Parcel, true /*owns*/) {}
    AParcel(AIBinder* binder, ::android::Parcel* parcel, bool owns)
        : mBinder(binder), mParcel(parcel), mOwns(owns) {
        if (binder != nullptr) {
            parcel->markForBinder(binder->getBinder());
        }
    }
        : mBinder(binder), mParcel(parcel), mOwns(owns) {}

    ~AParcel() {
        if (mOwns) {
Loading