Add fuzzer for remote access HAL.
Test: m -j android.hardware.automotive.remoteaccess@V1-default-service.aidl_fuzzer
cd [output_dir]
adb push ./data/fuzz/x86_64 /data/fuzz/x86_64
adb shell
/data/fuzz/x86_64/android.hardware.automotive.remoteaccess@V1-default-service.aidl_fuzzer/android.hardware.automotive.remoteaccess@V1-default-service.aidl_fuzzer
Bug: 241483300
Change-Id: I150e4aaf33b3732586341f8c55076d4eda687876
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index 51be330..a2bf86c 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -47,7 +47,7 @@
cc_library {
name: "RemoteAccessService",
- vendor: true,
+ vendor_available: true,
local_include_dirs: ["include"],
export_include_dirs: ["include"],
srcs: [
@@ -74,3 +74,36 @@
"-Wno-unused-parameter",
],
}
+
+cc_fuzz {
+ name: "android.hardware.automotive.remoteaccess@V1-default-service.aidl_fuzzer",
+ srcs: ["fuzzer/fuzzer.cpp"],
+ whole_static_libs: [
+ "RemoteAccessService",
+ ],
+ static_libs: [
+ "libgtest",
+ "libgmock",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "liblog",
+ "libutils",
+ "libgrpc++",
+ "libprotobuf-cpp-full",
+ ],
+ defaults: [
+ "vhalclient_defaults",
+ "service_fuzzer_defaults",
+ ],
+ cflags: [
+ "-Wno-unused-parameter",
+ "-DGRPC_SERVICE_ADDRESS=\"localhost:50051\"",
+ ],
+ fuzz_config: {
+ cc: [
+ "shanyu@google.com",
+ ],
+ },
+}
diff --git a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
new file mode 100644
index 0000000..292c80e
--- /dev/null
+++ b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 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 <RemoteAccessService.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gmock/gmock.h>
+#include <grpcpp/test/mock_stream.h>
+#include <wakeup_client.grpc.pb.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace remoteaccess {
+
+using ::grpc::ClientAsyncReaderInterface;
+using ::grpc::ClientAsyncResponseReaderInterface;
+using ::grpc::ClientContext;
+using ::grpc::ClientReader;
+using ::grpc::ClientReaderInterface;
+using ::grpc::CompletionQueue;
+using ::grpc::Status;
+using ::grpc::testing::MockClientReader;
+using ::testing::_;
+using ::testing::Return;
+
+class MockGrpcClientStub : public WakeupClient::StubInterface {
+ public:
+ ClientReaderInterface<GetRemoteTasksResponse>* GetRemoteTasksRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const GetRemoteTasksRequest& request) override {
+ MockClientReader<GetRemoteTasksResponse>* mockClientReader =
+ new MockClientReader<GetRemoteTasksResponse>();
+ ON_CALL(*mockClientReader, Finish()).WillByDefault(Return(Status::OK));
+ ON_CALL(*mockClientReader, Read(_)).WillByDefault(Return(false));
+ return mockClientReader;
+ }
+
+ Status NotifyWakeupRequired([[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+ [[maybe_unused]] NotifyWakeupRequiredResponse* response) {
+ return Status::OK;
+ }
+
+ // Async methods which we do not care.
+ ClientAsyncReaderInterface<GetRemoteTasksResponse>* AsyncGetRemoteTasksRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const GetRemoteTasksRequest& request,
+ [[maybe_unused]] CompletionQueue* cq, [[maybe_unused]] void* tag) {
+ return nullptr;
+ }
+
+ ClientAsyncReaderInterface<GetRemoteTasksResponse>* PrepareAsyncGetRemoteTasksRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const GetRemoteTasksRequest& request,
+ [[maybe_unused]] CompletionQueue* cq) {
+ return nullptr;
+ }
+
+ ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>* AsyncNotifyWakeupRequiredRaw(
+ [[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+ [[maybe_unused]] CompletionQueue* cq) {
+ return nullptr;
+ }
+
+ ClientAsyncResponseReaderInterface<NotifyWakeupRequiredResponse>*
+ PrepareAsyncNotifyWakeupRequiredRaw([[maybe_unused]] ClientContext* context,
+ [[maybe_unused]] const NotifyWakeupRequiredRequest& request,
+ [[maybe_unused]] CompletionQueue* c) {
+ return nullptr;
+ }
+};
+
+} // namespace remoteaccess
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ android::hardware::automotive::remoteaccess::MockGrpcClientStub stub;
+ std::shared_ptr<android::hardware::automotive::remoteaccess::RemoteAccessService> service =
+ ndk::SharedRefBase::make<
+ android::hardware::automotive::remoteaccess::RemoteAccessService>(&stub);
+ android::fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/automotive/remoteaccess/hal/default/proto/Android.bp b/automotive/remoteaccess/hal/default/proto/Android.bp
index 31b9d0e..3e0dba1 100644
--- a/automotive/remoteaccess/hal/default/proto/Android.bp
+++ b/automotive/remoteaccess/hal/default/proto/Android.bp
@@ -35,7 +35,6 @@
"wakeup_client.pb.h",
"wakeup_client.grpc.pb.h",
],
- vendor: true,
}
genrule {
@@ -52,12 +51,11 @@
"wakeup_client.pb.cc",
"wakeup_client.grpc.pb.cc",
],
- vendor: true,
}
cc_library_static {
name: "wakeup_client_protos",
- vendor: true,
+ vendor_available: true,
host_supported: true,
include_dirs: [
"external/protobuf/src",
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 72f37d7..5cd58d3 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -174,6 +174,7 @@
}
ScopedAStatus RemoteAccessService::getDeviceId(std::string* deviceId) {
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
auto vhalClient = IVhalClient::tryCreate();
if (vhalClient == nullptr) {
ALOGE("Failed to connect to VHAL");
@@ -181,6 +182,10 @@
/*errorCode=*/0, "Failed to connect to VHAL to get device ID");
}
return getDeviceIdWithClient(*vhalClient.get(), deviceId);
+#else
+ // Don't use VHAL client in fuzzing since IPC is not allowed.
+ return ScopedAStatus::ok();
+#endif
}
ScopedAStatus RemoteAccessService::getDeviceIdWithClient(IVhalClient& vhalClient,