Loading libs/binder/RpcConnection.cpp +25 −9 Original line number Diff line number Diff line Loading @@ -79,11 +79,11 @@ private: }; bool RpcConnection::setupUnixDomainServer(const char* path) { return addServer(UnixSocketAddress(path)); return setupSocketServer(UnixSocketAddress(path)); } bool RpcConnection::addUnixDomainClient(const char* path) { return addClient(UnixSocketAddress(path)); return addSocketClient(UnixSocketAddress(path)); } #ifdef __BIONIC__ Loading Loading @@ -111,15 +111,27 @@ bool RpcConnection::setupVsockServer(unsigned int port) { // realizing value w/ this type at compile time to avoid ubsan abort constexpr unsigned int kAnyCid = VMADDR_CID_ANY; return addServer(VsockSocketAddress(kAnyCid, port)); return setupSocketServer(VsockSocketAddress(kAnyCid, port)); } bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) { return addClient(VsockSocketAddress(cid, port)); return addSocketClient(VsockSocketAddress(cid, port)); } #endif // __BIONIC__ bool RpcConnection::addNullDebuggingClient() { unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC))); if (serverFd == -1) { ALOGE("Could not connect to /dev/null: %s", strerror(errno)); return false; } addClient(std::move(serverFd)); return true; } sp<IBinder> RpcConnection::getRootObject() { ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT); return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this)); Loading Loading @@ -180,7 +192,7 @@ wp<RpcServer> RpcConnection::server() { return mForServer; } bool RpcConnection::addServer(const SocketAddress& addr) { bool RpcConnection::setupSocketServer(const SocketAddress& addr) { LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server."); unique_fd serverFd( Loading @@ -206,7 +218,7 @@ bool RpcConnection::addServer(const SocketAddress& addr) { return true; } bool RpcConnection::addClient(const SocketAddress& addr) { bool RpcConnection::addSocketClient(const SocketAddress& addr) { unique_fd serverFd( TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0))); if (serverFd == -1) { Loading @@ -223,14 +235,18 @@ bool RpcConnection::addClient(const SocketAddress& addr) { LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get()); addClient(std::move(serverFd)); return true; } void RpcConnection::addClient(unique_fd&& fd) { std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = sp<ConnectionSocket>::make(); connection->fd = std::move(serverFd); connection->fd = std::move(fd); mClients.push_back(connection); return true; } void RpcConnection::assignServerToThisThread(base::unique_fd&& fd) { void RpcConnection::assignServerToThisThread(unique_fd&& fd) { std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = sp<ConnectionSocket>::make(); connection->fd = std::move(fd); Loading libs/binder/include/binder/Parcel.h +4 −4 Original line number Diff line number Diff line Loading @@ -101,6 +101,10 @@ 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; Loading Loading @@ -536,10 +540,6 @@ 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(); Loading libs/binder/include/binder/RpcConnection.h +12 −2 Original line number Diff line number Diff line Loading @@ -73,6 +73,15 @@ public: [[nodiscard]] bool addVsockClient(unsigned int cvd, unsigned int port); #endif // __BIONIC__ /** * For debugging! * * Sets up an empty socket. All queries to this socket which require a * response will never be satisfied. All data sent here will be * unceremoniously cast down the bottomless pit, /dev/null. */ [[nodiscard]] bool addNullDebuggingClient(); /** * Query the other side of the connection for the root object hosted by that * process's RpcServer (if one exists) Loading Loading @@ -109,8 +118,9 @@ private: friend sp<RpcConnection>; RpcConnection(); bool addServer(const SocketAddress& address); bool addClient(const SocketAddress& address); bool setupSocketServer(const SocketAddress& address); bool addSocketClient(const SocketAddress& address); void addClient(base::unique_fd&& fd); void assignServerToThisThread(base::unique_fd&& fd); struct ConnectionSocket : public RefBase { Loading libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h +7 −0 Original line number Diff line number Diff line Loading @@ -20,5 +20,12 @@ #include <fuzzer/FuzzedDataProvider.h> namespace android { /** * Fill parcel data, including some random binder objects and FDs */ void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider); /** * Fill parcel data, but don't fill any objects. */ void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider); } // namespace android libs/binder/parcel_fuzzer/main.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <iostream> #include <android-base/logging.h> #include <binder/RpcConnection.h> #include <fuzzbinder/random_parcel.h> #include <fuzzer/FuzzedDataProvider.h> Loading @@ -32,6 +33,8 @@ #include <sys/time.h> using android::fillRandomParcel; using android::RpcConnection; using android::sp; void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) { // TODO: functionality to create random parcels for libhwbinder parcels Loading @@ -56,7 +59,18 @@ void doFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads, provider.ConsumeIntegralInRange<size_t>(0, maxInstructions)); P p; if constexpr (std::is_same_v<P, android::Parcel>) { if (provider.ConsumeBool()) { auto connection = sp<RpcConnection>::make(); CHECK(connection->addNullDebuggingClient()); p.markForRpc(connection); fillRandomParcelData(&p, std::move(provider)); } else { fillRandomParcel(&p, std::move(provider)); } } else { fillRandomParcel(&p, std::move(provider)); } // since we are only using a byte to index CHECK(reads.size() <= 255) << reads.size(); Loading Loading
libs/binder/RpcConnection.cpp +25 −9 Original line number Diff line number Diff line Loading @@ -79,11 +79,11 @@ private: }; bool RpcConnection::setupUnixDomainServer(const char* path) { return addServer(UnixSocketAddress(path)); return setupSocketServer(UnixSocketAddress(path)); } bool RpcConnection::addUnixDomainClient(const char* path) { return addClient(UnixSocketAddress(path)); return addSocketClient(UnixSocketAddress(path)); } #ifdef __BIONIC__ Loading Loading @@ -111,15 +111,27 @@ bool RpcConnection::setupVsockServer(unsigned int port) { // realizing value w/ this type at compile time to avoid ubsan abort constexpr unsigned int kAnyCid = VMADDR_CID_ANY; return addServer(VsockSocketAddress(kAnyCid, port)); return setupSocketServer(VsockSocketAddress(kAnyCid, port)); } bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) { return addClient(VsockSocketAddress(cid, port)); return addSocketClient(VsockSocketAddress(cid, port)); } #endif // __BIONIC__ bool RpcConnection::addNullDebuggingClient() { unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC))); if (serverFd == -1) { ALOGE("Could not connect to /dev/null: %s", strerror(errno)); return false; } addClient(std::move(serverFd)); return true; } sp<IBinder> RpcConnection::getRootObject() { ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT); return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this)); Loading Loading @@ -180,7 +192,7 @@ wp<RpcServer> RpcConnection::server() { return mForServer; } bool RpcConnection::addServer(const SocketAddress& addr) { bool RpcConnection::setupSocketServer(const SocketAddress& addr) { LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server."); unique_fd serverFd( Loading @@ -206,7 +218,7 @@ bool RpcConnection::addServer(const SocketAddress& addr) { return true; } bool RpcConnection::addClient(const SocketAddress& addr) { bool RpcConnection::addSocketClient(const SocketAddress& addr) { unique_fd serverFd( TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0))); if (serverFd == -1) { Loading @@ -223,14 +235,18 @@ bool RpcConnection::addClient(const SocketAddress& addr) { LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get()); addClient(std::move(serverFd)); return true; } void RpcConnection::addClient(unique_fd&& fd) { std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = sp<ConnectionSocket>::make(); connection->fd = std::move(serverFd); connection->fd = std::move(fd); mClients.push_back(connection); return true; } void RpcConnection::assignServerToThisThread(base::unique_fd&& fd) { void RpcConnection::assignServerToThisThread(unique_fd&& fd) { std::lock_guard<std::mutex> _l(mSocketMutex); sp<ConnectionSocket> connection = sp<ConnectionSocket>::make(); connection->fd = std::move(fd); Loading
libs/binder/include/binder/Parcel.h +4 −4 Original line number Diff line number Diff line Loading @@ -101,6 +101,10 @@ 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; Loading Loading @@ -536,10 +540,6 @@ 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(); Loading
libs/binder/include/binder/RpcConnection.h +12 −2 Original line number Diff line number Diff line Loading @@ -73,6 +73,15 @@ public: [[nodiscard]] bool addVsockClient(unsigned int cvd, unsigned int port); #endif // __BIONIC__ /** * For debugging! * * Sets up an empty socket. All queries to this socket which require a * response will never be satisfied. All data sent here will be * unceremoniously cast down the bottomless pit, /dev/null. */ [[nodiscard]] bool addNullDebuggingClient(); /** * Query the other side of the connection for the root object hosted by that * process's RpcServer (if one exists) Loading Loading @@ -109,8 +118,9 @@ private: friend sp<RpcConnection>; RpcConnection(); bool addServer(const SocketAddress& address); bool addClient(const SocketAddress& address); bool setupSocketServer(const SocketAddress& address); bool addSocketClient(const SocketAddress& address); void addClient(base::unique_fd&& fd); void assignServerToThisThread(base::unique_fd&& fd); struct ConnectionSocket : public RefBase { Loading
libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h +7 −0 Original line number Diff line number Diff line Loading @@ -20,5 +20,12 @@ #include <fuzzer/FuzzedDataProvider.h> namespace android { /** * Fill parcel data, including some random binder objects and FDs */ void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider); /** * Fill parcel data, but don't fill any objects. */ void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider); } // namespace android
libs/binder/parcel_fuzzer/main.cpp +15 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <iostream> #include <android-base/logging.h> #include <binder/RpcConnection.h> #include <fuzzbinder/random_parcel.h> #include <fuzzer/FuzzedDataProvider.h> Loading @@ -32,6 +33,8 @@ #include <sys/time.h> using android::fillRandomParcel; using android::RpcConnection; using android::sp; void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) { // TODO: functionality to create random parcels for libhwbinder parcels Loading @@ -56,7 +59,18 @@ void doFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads, provider.ConsumeIntegralInRange<size_t>(0, maxInstructions)); P p; if constexpr (std::is_same_v<P, android::Parcel>) { if (provider.ConsumeBool()) { auto connection = sp<RpcConnection>::make(); CHECK(connection->addNullDebuggingClient()); p.markForRpc(connection); fillRandomParcelData(&p, std::move(provider)); } else { fillRandomParcel(&p, std::move(provider)); } } else { fillRandomParcel(&p, std::move(provider)); } // since we are only using a byte to index CHECK(reads.size() <= 255) << reads.size(); Loading