@@ -2728,6 +2728,65 @@ size_t Parcel::ipcObjectsCount() const
27282728 return 0 ;
27292729}
27302730
2731+ static void do_nothing_release_func (const uint8_t * data, size_t dataSize,
2732+ const binder_size_t * objects, size_t objectsCount) {
2733+ (void )data;
2734+ (void )dataSize;
2735+ (void )objects;
2736+ (void )objectsCount;
2737+ }
2738+ static void delete_data_release_func (const uint8_t * data, size_t dataSize,
2739+ const binder_size_t * objects, size_t objectsCount) {
2740+ delete[] data;
2741+ (void )dataSize;
2742+ (void )objects;
2743+ (void )objectsCount;
2744+ }
2745+
2746+ void Parcel::makeDangerousViewOf (Parcel* p) {
2747+ if (p->isForRpc ()) {
2748+ // warning: this must match the logic in rpcSetDataReference
2749+ auto * rf = p->maybeRpcFields ();
2750+ LOG_ALWAYS_FATAL_IF (rf == nullptr );
2751+ std::vector<std::variant<binder::unique_fd, binder::borrowed_fd>> fds;
2752+ if (rf->mFds ) {
2753+ fds.reserve (rf->mFds ->size ());
2754+ for (const auto & fd : *rf->mFds ) {
2755+ fds.push_back (binder::borrowed_fd (toRawFd (fd)));
2756+ }
2757+ }
2758+ status_t result =
2759+ rpcSetDataReference (rf->mSession , p->mData , p->mDataSize ,
2760+ rf->mObjectPositions .data (), rf->mObjectPositions .size (),
2761+ std::move (fds), do_nothing_release_func);
2762+ LOG_ALWAYS_FATAL_IF (result != OK, " Failed: %s" , statusToString (result).c_str ());
2763+ } else {
2764+ #ifdef BINDER_WITH_KERNEL_IPC
2765+ // warning: this must match the logic in ipcSetDataReference
2766+ auto * kf = p->maybeKernelFields ();
2767+ LOG_ALWAYS_FATAL_IF (kf == nullptr );
2768+
2769+ // Ownership of FDs is passed to the Parcel from kernel binder. This should be refactored
2770+ // to move this ownership out of Parcel and into release_func. However, today, Parcel
2771+ // always assums it can own and close FDs today. So, for purposes of testing consistency,
2772+ // , create new FDs it can own.
2773+
2774+ uint8_t * newData = new uint8_t [p->mDataSize ]; // deleted by delete_data_release_func
2775+ memcpy (newData, p->mData , p->mDataSize );
2776+ for (size_t i = 0 ; i < kf->mObjectsSize ; i++) {
2777+ flat_binder_object* flat =
2778+ reinterpret_cast <flat_binder_object*>(newData + kf->mObjects [i]);
2779+ if (flat->hdr .type == BINDER_TYPE_FD) {
2780+ flat->handle = fcntl (flat->handle , F_DUPFD_CLOEXEC, 0 );
2781+ }
2782+ }
2783+
2784+ ipcSetDataReference (newData, p->mDataSize , kf->mObjects , kf->mObjectsSize ,
2785+ delete_data_release_func);
2786+ #endif // BINDER_WITH_KERNEL_IPC
2787+ }
2788+ }
2789+
27312790void Parcel::ipcSetDataReference (const uint8_t * data, size_t dataSize, const binder_size_t * objects,
27322791 size_t objectsCount, release_func relFunc) {
27332792 // this code uses 'mOwner == nullptr' to understand whether it owns memory
@@ -2738,6 +2797,7 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, const bin
27382797 auto * kernelFields = maybeKernelFields ();
27392798 LOG_ALWAYS_FATAL_IF (kernelFields == nullptr ); // guaranteed by freeData.
27402799
2800+ // must match makeDangerousViewOf
27412801 mData = const_cast <uint8_t *>(data);
27422802 mDataSize = mDataCapacity = dataSize;
27432803 kernelFields->mObjects = const_cast <binder_size_t *>(objects);
@@ -2816,6 +2876,7 @@ status_t Parcel::rpcSetDataReference(
28162876 auto * rpcFields = maybeRpcFields ();
28172877 LOG_ALWAYS_FATAL_IF (rpcFields == nullptr ); // guaranteed by markForRpc.
28182878
2879+ // must match makeDangerousViewOf
28192880 mData = const_cast <uint8_t *>(data);
28202881 mDataSize = mDataCapacity = dataSize;
28212882 mOwner = relFunc;
0 commit comments