diff options
60 files changed, 261 insertions, 32 deletions
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp index d73a30bf9b..fb69513d24 100644 --- a/cmds/servicemanager/Android.bp +++ b/cmds/servicemanager/Android.bp @@ -93,9 +93,22 @@ cc_fuzz { libfuzzer_options: [ "max_len=50000", ], - cc: [ - "smoreland@google.com", - "waghpawan@google.com", + }, +} + +// Adding this new fuzzer to test the corpus generated by record_binder +cc_fuzz { + name: "servicemanager_test_fuzzer", + defaults: [ + "servicemanager_defaults", + "service_fuzzer_defaults", + ], + host_supported: true, + srcs: ["fuzzers/ServiceManagerTestFuzzer.cpp"], + fuzz_config: { + libfuzzer_options: [ + "max_len=50000", ], }, + corpus: ["fuzzers/servicemamanager_fuzzer_corpus/*"], } diff --git a/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp b/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp new file mode 100644 index 0000000000..e19b6eb279 --- /dev/null +++ b/cmds/servicemanager/fuzzers/ServiceManagerTestFuzzer.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fuzzbinder/libbinder_driver.h> +#include <utils/StrongPointer.h> + +#include "Access.h" +#include "ServiceManager.h" + +using ::android::Access; +using ::android::Parcel; +using ::android::ServiceManager; +using ::android::sp; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider provider(data, size); + auto accessPtr = std::make_unique<Access>(); + auto serviceManager = sp<ServiceManager>::make(std::move(accessPtr)); + + // Reserved bytes + provider.ConsumeBytes<uint8_t>(8); + uint32_t code = provider.ConsumeIntegral<uint32_t>(); + uint32_t flag = provider.ConsumeIntegral<uint32_t>(); + std::vector<uint8_t> parcelData = provider.ConsumeRemainingBytes<uint8_t>(); + + Parcel inputParcel; + inputParcel.setData(parcelData.data(), parcelData.size()); + + Parcel reply; + serviceManager->transact(code, inputParcel, &reply, flag); + + serviceManager->clear(); + + return 0; +} diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_1 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10 Binary files differnew file mode 100644 index 0000000000..07319f864e --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_10 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_11 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12 Binary files differnew file mode 100644 index 0000000000..07319f864e --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_12 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_13 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14 Binary files differnew file mode 100644 index 0000000000..07319f864e --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_14 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_15 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16 Binary files differnew file mode 100644 index 0000000000..07319f864e --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_16 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_17 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18 Binary files differnew file mode 100644 index 0000000000..88ad474f09 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_18 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19 Binary files differnew file mode 100644 index 0000000000..fae15a2fea --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_19 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2 Binary files differnew file mode 100644 index 0000000000..e69ab49d5d --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_2 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_20 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21 Binary files differnew file mode 100644 index 0000000000..88ad474f09 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_21 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22 Binary files differnew file mode 100644 index 0000000000..fae15a2fea --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_22 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_23 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24 Binary files differnew file mode 100644 index 0000000000..88ad474f09 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_24 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25 Binary files differnew file mode 100644 index 0000000000..fae15a2fea --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_25 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_26 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27 Binary files differnew file mode 100644 index 0000000000..88ad474f09 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_27 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28 Binary files differnew file mode 100644 index 0000000000..fae15a2fea --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_28 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_29 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_3 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30 Binary files differnew file mode 100644 index 0000000000..88ad474f09 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_30 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31 Binary files differnew file mode 100644 index 0000000000..fae15a2fea --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_31 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_32 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33 Binary files differnew file mode 100644 index 0000000000..88ad474f09 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_33 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34 Binary files differnew file mode 100644 index 0000000000..fae15a2fea --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_34 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_35 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36 Binary files differnew file mode 100644 index 0000000000..88ad474f09 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_36 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37 Binary files differnew file mode 100644 index 0000000000..fae15a2fea --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_37 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_38 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39 Binary files differnew file mode 100644 index 0000000000..b326907a58 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_39 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4 Binary files differnew file mode 100644 index 0000000000..05b27bf413 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_4 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_40 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41 Binary files differnew file mode 100644 index 0000000000..b326907a58 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_41 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42 Binary files differnew file mode 100644 index 0000000000..cdaa1f01b1 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_42 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43 Binary files differnew file mode 100644 index 0000000000..ff0941b7a6 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_43 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44 Binary files differnew file mode 100644 index 0000000000..cdaa1f01b1 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_44 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_45 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46 Binary files differnew file mode 100644 index 0000000000..7e5f948682 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_46 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_5 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6 Binary files differnew file mode 100644 index 0000000000..07319f864e --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_6 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_7 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8 Binary files differnew file mode 100644 index 0000000000..07319f864e --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_8 diff --git a/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9 b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9 Binary files differnew file mode 100644 index 0000000000..39e5104927 --- /dev/null +++ b/cmds/servicemanager/fuzzers/servicemanager_fuzzer_corpus/Transaction_9 diff --git a/cmds/servicemanager/servicemanager.recovery.rc b/cmds/servicemanager/servicemanager.recovery.rc index b927c018df..6354fd7d53 100644 --- a/cmds/servicemanager/servicemanager.recovery.rc +++ b/cmds/servicemanager/servicemanager.recovery.rc @@ -1,5 +1,6 @@ service servicemanager /system/bin/servicemanager disabled group system readproc + user root onrestart setprop servicemanager.ready false seclabel u:r:servicemanager:s0 diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 2408307459..d4ef0b73a1 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -412,13 +412,11 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) // command, so we hang indefinitely. std::unique_lock<std::mutex> lock(waiter->mMutex); using std::literals::chrono_literals::operator""s; - waiter->mCv.wait_for(lock, 1s, [&] { - return waiter->mBinder != nullptr; - }); + waiter->mCv.wait_for(lock, 2s, [&] { return waiter->mBinder != nullptr; }); if (waiter->mBinder != nullptr) return waiter->mBinder; } - ALOGW("Waited one second for %s (is service started? Number of threads started in the " + ALOGW("Waited two seconds for %s (is service started? Number of threads started in the " "threadpool: %zu. Are binder threads started and available?)", name.c_str(), ProcessState::self()->getThreadPoolMaxTotalThreadCount()); diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp index f66993f926..7644806e2b 100644 --- a/libs/binder/LazyServiceRegistrar.cpp +++ b/libs/binder/LazyServiceRegistrar.cpp @@ -324,6 +324,10 @@ LazyServiceRegistrar& LazyServiceRegistrar::getInstance() { return *registrarInstance; } +LazyServiceRegistrar LazyServiceRegistrar::createExtraTestInstance() { + return LazyServiceRegistrar(); +} + status_t LazyServiceRegistrar::registerService(const sp<IBinder>& service, const std::string& name, bool allowIsolated, int dumpFlags) { if (!mClientCC->registerService(service, name, allowIsolated, dumpFlags)) { diff --git a/libs/binder/RecordedTransaction.cpp b/libs/binder/RecordedTransaction.cpp index 1c7613584b..44a9e3befa 100644 --- a/libs/binder/RecordedTransaction.cpp +++ b/libs/binder/RecordedTransaction.cpp @@ -161,17 +161,6 @@ static_assert(sizeof(ChunkDescriptor) % 8 == 0); constexpr uint32_t kMaxChunkDataSize = 0xfffffff0; typedef uint64_t transaction_checksum_t; -static android::status_t readChunkDescriptor(borrowed_fd fd, ChunkDescriptor* chunkOut, - transaction_checksum_t* sum) { - if (!android::base::ReadFully(fd, chunkOut, sizeof(ChunkDescriptor))) { - LOG(ERROR) << "Failed to read Chunk Descriptor from fd " << fd.get(); - return android::UNKNOWN_ERROR; - } - - *sum ^= *reinterpret_cast<transaction_checksum_t*>(chunkOut); - return android::NO_ERROR; -} - std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd& fd) { RecordedTransaction t; ChunkDescriptor chunk; @@ -192,11 +181,13 @@ std::optional<RecordedTransaction> RecordedTransaction::fromFile(const unique_fd LOG(ERROR) << "Not enough file remains to contain expected chunk descriptor"; return std::nullopt; } - transaction_checksum_t checksum = 0; - if (NO_ERROR != readChunkDescriptor(fd, &chunk, &checksum)) { - LOG(ERROR) << "Failed to read chunk descriptor."; + + if (!android::base::ReadFully(fd, &chunk, sizeof(ChunkDescriptor))) { + LOG(ERROR) << "Failed to read ChunkDescriptor from fd " << fd.get() << ". " + << strerror(errno); return std::nullopt; } + transaction_checksum_t checksum = *reinterpret_cast<transaction_checksum_t*>(&chunk); fdCurrentPosition = lseek(fd.get(), 0, SEEK_CUR); if (fdCurrentPosition == -1) { diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index ed3ce24e46..03fa69973d 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -928,7 +928,7 @@ processTransactInternalTailCall: transactionData.size() - offsetof(RpcWireTransaction, data)}; Span<const uint32_t> objectTableSpan; - if (session->getProtocolVersion().value() > + if (session->getProtocolVersion().value() >= RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_SIZE) { std::optional<Span<const uint8_t>> objectTableBytes = parcelSpan.splitOff(transaction->parcelDataSize); diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h index d960a0b894..744da0f825 100644 --- a/libs/binder/include/binder/Binder.h +++ b/libs/binder/include/binder/Binder.h @@ -105,12 +105,6 @@ public: [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd clientFd, const sp<IBinder>& keepAliveBinder); - // Start recording transactions to the unique_fd in data. - // See RecordedTransaction.h for more details. - [[nodiscard]] status_t startRecordingTransactions(const Parcel& data); - // Stop the current recording. - [[nodiscard]] status_t stopRecordingTransactions(); - protected: virtual ~BBinder(); @@ -131,6 +125,8 @@ private: [[nodiscard]] status_t setRpcClientDebug(const Parcel& data); void removeRpcServerLink(const sp<RpcServerLink>& link); + [[nodiscard]] status_t startRecordingTransactions(const Parcel& data); + [[nodiscard]] status_t stopRecordingTransactions(); std::atomic<Extras*> mExtras; diff --git a/libs/binder/include/binder/LazyServiceRegistrar.h b/libs/binder/include/binder/LazyServiceRegistrar.h index 2e22b84ff0..bda3d19ee1 100644 --- a/libs/binder/include/binder/LazyServiceRegistrar.h +++ b/libs/binder/include/binder/LazyServiceRegistrar.h @@ -93,7 +93,17 @@ class LazyServiceRegistrar { */ void reRegister(); - private: + /** + * Create a second instance of lazy service registrar. + * + * WARNING: dangerous! DO NOT USE THIS - LazyServiceRegistrar + * should be single-instanced, so that the service will only + * shut down when all services are unused. A separate instance + * is only used to test race conditions. + */ + static LazyServiceRegistrar createExtraTestInstance(); + + private: std::shared_ptr<internal::ClientCounterCallback> mClientCC; LazyServiceRegistrar(); }; diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h index a323febbc7..cb6460398d 100644 --- a/libs/binder/include/binder/RpcSession.h +++ b/libs/binder/include/binder/RpcSession.h @@ -37,9 +37,9 @@ class RpcState; class RpcTransport; class FdTrigger; -constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_NEXT = 1; +constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_NEXT = 2; constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL = 0xF0000000; -constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION = RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL; +constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION = 1; // Starting with this version: // diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index 56f4ac7fe5..cad364d8e8 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -67,6 +67,28 @@ cc_test { } cc_test { + name: "binderRecordReplayTest", + srcs: ["binderRecordReplayTest.cpp"], + shared_libs: [ + "libbinder", + "libcutils", + "libutils", + ], + static_libs: [ + "binderRecordReplayTestIface-cpp", + ], + test_suites: ["general-tests"], +} + +aidl_interface { + name: "binderRecordReplayTestIface", + unstable: true, + srcs: [ + "IBinderRecordReplayTest.aidl", + ], +} + +cc_test { name: "binderLibTest", defaults: ["binder_test_defaults"], diff --git a/libs/binder/tests/IBinderRecordReplayTest.aidl b/libs/binder/tests/IBinderRecordReplayTest.aidl new file mode 100644 index 0000000000..3c8c722da4 --- /dev/null +++ b/libs/binder/tests/IBinderRecordReplayTest.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface IBinderRecordReplayTest { + void setInt(int input); + int getInt(); +} diff --git a/libs/binder/tests/binderRecordReplayTest.cpp b/libs/binder/tests/binderRecordReplayTest.cpp new file mode 100644 index 0000000000..55148acf14 --- /dev/null +++ b/libs/binder/tests/binderRecordReplayTest.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <BnBinderRecordReplayTest.h> +#include <android-base/logging.h> +#include <android-base/unique_fd.h> +#include <binder/Binder.h> +#include <binder/BpBinder.h> +#include <binder/IBinder.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <binder/RecordedTransaction.h> +#include <gtest/gtest.h> + +#include <sys/prctl.h> + +using namespace android; +using android::binder::Status; +using android::binder::debug::RecordedTransaction; + +const String16 kServerName = String16("binderRecordReplay"); + +class MyRecordReplay : public BnBinderRecordReplayTest { +public: + Status setInt(int input) { + mInt = input; + return Status::ok(); + } + Status getInt(int* output) { + *output = mInt; + return Status::ok(); + } + +private: + int mInt = 0; +}; + +TEST(BinderClearBuf, RecordReplayRepeatInt) { + // get the remote service + sp<IBinder> binder = defaultServiceManager()->getService(kServerName); + ASSERT_NE(nullptr, binder); + sp<IBinderRecordReplayTest> iface = interface_cast<IBinderRecordReplayTest>(binder); + sp<BpBinder> bpBinder = binder->remoteBinder(); + ASSERT_NE(nullptr, bpBinder); + + base::unique_fd fd( + open("/data/local/tmp/binderRecordReplayTest.rec", O_RDWR | O_CREAT | O_CLOEXEC, 0666)); + ASSERT_TRUE(fd.ok()); + + // record a transaction + bpBinder->startRecordingBinder(fd); + EXPECT_TRUE(iface->setInt(3).isOk()); + bpBinder->stopRecordingBinder(); + + // test transaction does the thing we expect it to do + int output; + EXPECT_TRUE(iface->getInt(&output).isOk()); + EXPECT_EQ(output, 3); + + // write over the existing state + EXPECT_TRUE(iface->setInt(5).isOk()); + EXPECT_TRUE(iface->getInt(&output).isOk()); + EXPECT_EQ(output, 5); + + // replay transaction + ASSERT_EQ(0, lseek(fd.get(), 0, SEEK_SET)); + std::optional<RecordedTransaction> transaction = RecordedTransaction::fromFile(fd); + ASSERT_NE(transaction, std::nullopt); + + // TODO: move logic to replay RecordedTransaction into RecordedTransaction + Parcel data; + data.setData(transaction->getDataParcel().data(), transaction->getDataParcel().dataSize()); + status_t status = binder->remoteBinder()->transact(transaction->getCode(), data, nullptr, + transaction->getFlags()); + + // make sure recording does the thing we expect it to do + EXPECT_EQ(OK, status); + EXPECT_TRUE(iface->getInt(&output).isOk()); + EXPECT_EQ(output, 3); + + // TODO: we should also make sure we can convert the recording to a fuzzer + // corpus entry, and we will be able to replay it in the same way +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + if (fork() == 0) { + prctl(PR_SET_PDEATHSIG, SIGHUP); + + auto server = sp<MyRecordReplay>::make(); + android::defaultServiceManager()->addService(kServerName, server.get()); + + IPCThreadState::self()->joinThreadPool(true); + exit(1); // should not reach + } + + // not racey, but getService sleeps for 1s + usleep(100000); + + return RUN_ALL_TESTS(); +} diff --git a/libs/binder/tests/binderRpcWireProtocolTest.cpp b/libs/binder/tests/binderRpcWireProtocolTest.cpp index 3dab2c748b..642cea440d 100644 --- a/libs/binder/tests/binderRpcWireProtocolTest.cpp +++ b/libs/binder/tests/binderRpcWireProtocolTest.cpp @@ -237,14 +237,25 @@ TEST(RpcWire, V0) { checkRepr(kCurrentRepr, 0); } +TEST(RpcWire, V1) { + checkRepr(kCurrentRepr, 1); +} + TEST(RpcWire, CurrentVersion) { checkRepr(kCurrentRepr, RPC_WIRE_PROTOCOL_VERSION); } -static_assert(RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL, +static_assert(RPC_WIRE_PROTOCOL_VERSION == 1, "If the binder wire protocol is updated, this test should test additional versions. " "The binder wire protocol should only be updated on upstream AOSP."); +TEST(RpcWire, NextIsPlusOneReminder) { + if (RPC_WIRE_PROTOCOL_VERSION != RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) { + EXPECT_EQ(RPC_WIRE_PROTOCOL_VERSION + 1, RPC_WIRE_PROTOCOL_VERSION_NEXT) + << "Make sure to note what the next version should be."; + } +} + TEST(RpcWire, ReleaseBranchHasFrozenRpcWireProtocol) { if (RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) { EXPECT_FALSE(base::GetProperty("ro.build.version.codename", "") == "REL") |