add fuzz test and fix the Thread network HAL compile errors
Bug: 288825495
Test: Build and run fuzz test in cuttlefish
Change-Id: If14bd95657d6a71737a348ccbc6d1b05bbcc1f4c
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index 9fbf93e..93beb92 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -834,12 +834,4 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="aidl" optional="true">
- <name>android.hardware.threadnetwork</name>
- <version>1</version>
- <interface>
- <name>IThreadChip</name>
- <regex-instance>chip[0-9]+</regex-instance>
- </interface>
- </hal>
</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index e23f2ae..60bb2ab 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -794,4 +794,12 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.threadnetwork</name>
+ <version>1</version>
+ <interface>
+ <name>IThreadChip</name>
+ <regex-instance>chip[0-9]+</regex-instance>
+ </interface>
+ </hal>
</compatibility-matrix>
diff --git a/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index 201306d..736e808 100644
--- a/threadnetwork/aidl/default/Android.bp
+++ b/threadnetwork/aidl/default/Android.bp
@@ -24,10 +24,6 @@
"libutils",
],
- cppflags: [
- "-Wno-non-virtual-dtor",
- ],
-
static_libs: [
"openthread-common",
"openthread-hdlc",
@@ -48,9 +44,43 @@
name: "android.hardware.threadnetwork-service.sim",
defaults: ["threadnetwork_service_default"],
init_rc: ["android.hardware.threadnetwork-service.sim.rc"],
+ required: ["ot-rcp"],
}
cc_binary {
name: "android.hardware.threadnetwork-service",
defaults: ["threadnetwork_service_default"],
}
+
+cc_fuzz {
+ name: "android.hardware.threadnetwork-service.fuzzer",
+
+ defaults:["service_fuzzer_defaults"],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+
+ static_libs: [
+ "android.hardware.threadnetwork-V1-ndk",
+ "libbase",
+ "liblog",
+ "openthread-common",
+ "openthread-hdlc",
+ "openthread-platform",
+ "openthread-posix",
+ "openthread-url",
+ ],
+
+ srcs: [
+ "thread_chip.cpp",
+ "utils.cpp",
+ "fuzzer.cpp",
+ ],
+
+ required: ["ot-rcp"],
+ fuzz_config: {
+ cc: [
+ "zhanglongxia@google.com",
+ ],
+ },
+}
diff --git a/threadnetwork/aidl/default/fuzzer.cpp b/threadnetwork/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..512708d
--- /dev/null
+++ b/threadnetwork/aidl/default/fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include "thread_chip.hpp"
+
+using aidl::android::hardware::threadnetwork::ThreadChip;
+using android::fuzzService;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ char url[] = "spinel+hdlc+forkpty:///vendor/bin/ot-rcp?forkpty-arg=2";
+ auto service = ndk::SharedRefBase::make<ThreadChip>(url);
+
+ fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
+
+ return 0;
+}
+
diff --git a/threadnetwork/aidl/default/main.cpp b/threadnetwork/aidl/default/main.cpp
index 9f2a789..8419041 100644
--- a/threadnetwork/aidl/default/main.cpp
+++ b/threadnetwork/aidl/default/main.cpp
@@ -14,14 +14,37 @@
* limitations under the License.
*/
+#include <aidl/android/hardware/threadnetwork/IThreadChip.h>
#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
#include "service.hpp"
-#include "utils.hpp"
+#include "thread_chip.hpp"
+
+using aidl::android::hardware::threadnetwork::IThreadChip;
+using aidl::android::hardware::threadnetwork::ThreadChip;
int main(int argc, char* argv[]) {
CHECK_GT(argc, 1);
- aidl::android::hardware::threadnetwork::Service service(&argv[1], argc - 1);
+ std::vector<std::shared_ptr<ThreadChip>> threadChips;
+ aidl::android::hardware::threadnetwork::Service service;
+
+ for (int id = 0; id < argc - 1; id++) {
+ binder_status_t status;
+ const std::string serviceName(std::string() + IThreadChip::descriptor + "/chip" +
+ std::to_string(id));
+ auto threadChip = ndk::SharedRefBase::make<ThreadChip>(argv[id + 1]);
+
+ CHECK_NE(threadChip, nullptr);
+
+ status = AServiceManager_addService(threadChip->asBinder().get(), serviceName.c_str());
+ CHECK_EQ(status, STATUS_OK);
+
+ ALOGI("ServiceName: %s, Url: %s", serviceName.c_str(), argv[id + 1]);
+ threadChips.push_back(std::move(threadChip));
+ }
ALOGI("Thread Network HAL is running");
diff --git a/threadnetwork/aidl/default/service.cpp b/threadnetwork/aidl/default/service.cpp
index 44bb99a..7f583f4 100644
--- a/threadnetwork/aidl/default/service.cpp
+++ b/threadnetwork/aidl/default/service.cpp
@@ -18,25 +18,14 @@
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
-
-#include "thread_chip.hpp"
-#include "utils.hpp"
+#include <utils/Log.h>
namespace aidl {
namespace android {
namespace hardware {
namespace threadnetwork {
-Service::Service(char* urls[], int numUrls) : mBinderFd(-1) {
- CHECK_NE(urls, nullptr);
- CHECK_GT(numUrls, 0);
-
- for (int i = 0; i < numUrls; i++) {
- auto threadChip = ndk::SharedRefBase::make<ThreadChip>(i, urls[i]);
- CHECK_NE(threadChip, nullptr);
- mThreadChips.push_back(std::move(threadChip));
- }
-
+Service::Service(void) : mBinderFd(-1) {
binder_status_t status = ABinderProcess_setupPolling(&mBinderFd);
CHECK_EQ(status, ::STATUS_OK);
CHECK_GE(mBinderFd, 0);
diff --git a/threadnetwork/aidl/default/service.hpp b/threadnetwork/aidl/default/service.hpp
index 4137049..6a94791 100644
--- a/threadnetwork/aidl/default/service.hpp
+++ b/threadnetwork/aidl/default/service.hpp
@@ -15,7 +15,6 @@
*/
#include "mainloop.hpp"
-#include "thread_chip.hpp"
namespace aidl {
namespace android {
@@ -24,7 +23,7 @@
class Service : public ot::Posix::Mainloop::Source {
public:
- Service(char* urls[], int numUrls);
+ Service(void);
void Update(otSysMainloopContext& context) override;
void Process(const otSysMainloopContext& context) override;
@@ -32,7 +31,6 @@
private:
int mBinderFd;
- std::vector<std::shared_ptr<ThreadChip>> mThreadChips;
};
} // namespace threadnetwork
} // namespace hardware
diff --git a/threadnetwork/aidl/default/thread_chip.cpp b/threadnetwork/aidl/default/thread_chip.cpp
index b5cc7eb..e542c7c 100644
--- a/threadnetwork/aidl/default/thread_chip.cpp
+++ b/threadnetwork/aidl/default/thread_chip.cpp
@@ -19,26 +19,19 @@
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
-
-#include "utils.hpp"
+#include <utils/Log.h>
namespace aidl {
namespace android {
namespace hardware {
namespace threadnetwork {
-ThreadChip::ThreadChip(uint8_t id, char* url)
+ThreadChip::ThreadChip(char* url)
: mUrl(),
mInterface(handleReceivedFrame, this, mRxFrameBuffer),
mRxFrameBuffer(),
mCallback(nullptr) {
- const std::string name(std::string() + IThreadChip::descriptor + "/chip" + std::to_string(id));
- binder_status_t status;
-
- ALOGI("ServiceName: %s, Url: %s", name.c_str(), url);
CHECK_EQ(mUrl.Init(url), 0);
- status = AServiceManager_addService(asBinder().get(), name.c_str());
- CHECK_EQ(status, STATUS_OK);
}
void ThreadChip::clientDeathCallback(void* context) {
@@ -85,17 +78,13 @@
status = ndk::ScopedAStatus::ok();
exit:
- if (!status.isOk())
- {
- if (mBinderDeathRecipient != nullptr)
- {
- AIBinder_DeathRecipient_delete(mBinderDeathRecipient);
- mBinderDeathRecipient = nullptr;
+ if (!status.isOk()) {
+ if (mBinderDeathRecipient != nullptr) {
+ AIBinder_DeathRecipient_delete(mBinderDeathRecipient);
+ mBinderDeathRecipient = nullptr;
}
ALOGW("Open failed, error: %s", status.getDescription().c_str());
- }
- else
- {
+ } else {
ALOGI("open()");
}
@@ -137,8 +126,7 @@
}
exit:
- if (!status.isOk())
- {
+ if (!status.isOk()) {
ALOGW("Send spinel frame failed, error: %s", status.getDescription().c_str());
}
@@ -146,25 +134,20 @@
}
ndk::ScopedAStatus ThreadChip::reset() {
- mInterface.OnRcpReset();
+ mInterface.HardwareReset();
ALOGI("reset()");
return ndk::ScopedAStatus::ok();
}
void ThreadChip::Update(otSysMainloopContext& context) {
if (mCallback != nullptr) {
- mInterface.UpdateFdSet(context.mReadFdSet, context.mWriteFdSet, context.mMaxFd,
- context.mTimeout);
+ mInterface.UpdateFdSet(&context);
}
}
void ThreadChip::Process(const otSysMainloopContext& context) {
- struct RadioProcessContext radioContext;
-
if (mCallback != nullptr) {
- radioContext.mReadFdSet = &context.mReadFdSet;
- radioContext.mWriteFdSet = &context.mWriteFdSet;
- mInterface.Process(radioContext);
+ mInterface.Process(&context);
}
}
diff --git a/threadnetwork/aidl/default/thread_chip.hpp b/threadnetwork/aidl/default/thread_chip.hpp
index d444374..d93dfef 100644
--- a/threadnetwork/aidl/default/thread_chip.hpp
+++ b/threadnetwork/aidl/default/thread_chip.hpp
@@ -33,7 +33,7 @@
class ThreadChip : public BnThreadChip, ot::Posix::Mainloop::Source {
public:
- ThreadChip(uint8_t id, char* url);
+ ThreadChip(char* url);
ndk::ScopedAStatus open(const std::shared_ptr<IThreadChipCallback>& in_callback) override;
ndk::ScopedAStatus close() override;
diff --git a/threadnetwork/aidl/default/utils.cpp b/threadnetwork/aidl/default/utils.cpp
index a8f3464..b4da7d7 100644
--- a/threadnetwork/aidl/default/utils.cpp
+++ b/threadnetwork/aidl/default/utils.cpp
@@ -15,9 +15,10 @@
* limitations under the License.
*/
-#include "utils.hpp"
-
+#include <openthread/instance.h>
#include <openthread/logging.h>
+#include <openthread/platform/alarm-milli.h>
+#include <utils/Log.h>
void otLogCritPlat(const char* format, ...) {
va_list args;
@@ -34,3 +35,7 @@
__android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, args);
va_end(args);
}
+
+OT_TOOL_WEAK void otPlatAlarmMilliFired(otInstance* aInstance) {
+ OT_UNUSED_VARIABLE(aInstance);
+}
diff --git a/threadnetwork/aidl/default/utils.hpp b/threadnetwork/aidl/default/utils.hpp
deleted file mode 100644
index 279c0ba..0000000
--- a/threadnetwork/aidl/default/utils.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#define LOG_TAG "threadnetwork_hal"
-#include <utils/Log.h>