From 3fd1373b12fbf4585c20b9528e5fe6ac8a4732df Mon Sep 17 00:00:00 2001 From: Zongheng Wang Date: Wed, 16 Oct 2019 16:39:11 -0700 Subject: Add a fuzzer in bluetooth gd for l2cap dynamic channel allocator Initialized fuzz test for Bluetooth GD library. There is one fuzz target gd/fuzz_test.cc and it will call all fuzz tests in gd. Created a fuzzer for l2cap classic internal dynamic channel allocator to test DynamicChannelAllocator::IsPsmUsed(Psm psm). Bug: 142684649 Test: bluetooth_gd_fuzz_test Change-Id: If7c66d6aefc5d52448824f7f96f3118607a37215 --- system/gd/Android.bp | 28 +++++++ system/gd/fuzz_test.cc | 25 ++++++ system/gd/l2cap/Android.bp | 7 ++ .../dynamic_channel_allocator_fuzz_test.cc | 89 ++++++++++++++++++++++ system/gd/l2cap/classic/internal/link_mock.h | 4 + 5 files changed, 153 insertions(+) create mode 100644 system/gd/fuzz_test.cc create mode 100644 system/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc diff --git a/system/gd/Android.bp b/system/gd/Android.bp index a763cecb0d..5b44d2c03f 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -285,6 +285,34 @@ cc_test { }, } +cc_fuzz { + name: "bluetooth_gd_fuzz_test", + defaults: ["gd_defaults"], + srcs: [ + "fuzz_test.cc", + ":BluetoothL2capFuzzTestSources", + ], + static_libs: [ + "libbluetooth_gd", + "libchrome", + "libgmock", + "libgtest", + ], + host_supported: true, + generated_headers: [ + "BluetoothGeneratedPackets_h", + ], + target: { + android: { + shared_libs: [ + "android.hardware.bluetooth@1.0", + "libhidlbase", + "libutils", + ], + }, + }, +} + cc_benchmark { name: "bluetooth_benchmark_gd", defaults: ["gd_defaults"], diff --git a/system/gd/fuzz_test.cc b/system/gd/fuzz_test.cc new file mode 100644 index 0000000000..69a01aa4bb --- /dev/null +++ b/system/gd/fuzz_test.cc @@ -0,0 +1,25 @@ +/* + * Copyright 2019 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 +#include + +extern void RunL2capClassicDynamicChannelAllocatorFuzzTest(const uint8_t* data, size_t size); + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + RunL2capClassicDynamicChannelAllocatorFuzzTest(data, size); + return 0; +} \ No newline at end of file diff --git a/system/gd/l2cap/Android.bp b/system/gd/l2cap/Android.bp index f07762c6f3..633b31b31e 100644 --- a/system/gd/l2cap/Android.bp +++ b/system/gd/l2cap/Android.bp @@ -61,3 +61,10 @@ filegroup { "classic/cert/cert.cc", ], } + +filegroup { + name: "BluetoothL2capFuzzTestSources", + srcs: [ + "classic/internal/dynamic_channel_allocator_fuzz_test.cc", + ], +} diff --git a/system/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc b/system/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc new file mode 100644 index 0000000000..80d15184c6 --- /dev/null +++ b/system/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc @@ -0,0 +1,89 @@ +/* + * Copyright 2019 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 "l2cap/classic/internal/dynamic_channel_allocator.h" +#include "l2cap/classic/internal/link_mock.h" +#include "l2cap/internal/parameter_provider_mock.h" + +#include + +namespace bluetooth { +namespace l2cap { +namespace classic { +namespace internal { + +using hci::testing::MockAclConnection; +using l2cap::internal::testing::MockParameterProvider; +using l2cap::internal::testing::MockScheduler; +using testing::MockLink; +using ::testing::NiceMock; +using ::testing::Return; + +const hci::Address device{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}; + +class L2capClassicDynamicChannelAllocatorFuzzTest { + public: + void RunTests(const uint8_t* data, size_t size) { + SetUp(); + TestPrecondition(data, size); + TearDown(); + } + + private: + void SetUp() { + thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL); + handler_ = new os::Handler(thread_); + mock_parameter_provider_ = new NiceMock(); + mock_classic_link_ = + new NiceMock(handler_, mock_parameter_provider_, std::make_unique>(), + std::make_unique>()); + EXPECT_CALL(*mock_classic_link_, GetDevice()).WillRepeatedly(Return(device)); + channel_allocator_ = std::make_unique(mock_classic_link_, handler_); + } + + void TearDown() { + channel_allocator_.reset(); + delete mock_classic_link_; + delete mock_parameter_provider_; + handler_->Clear(); + delete handler_; + delete thread_; + } + + void TestPrecondition(const uint8_t* data, size_t size) { + if (size != 2) { + return; + } + Psm psm = *reinterpret_cast(data); + EXPECT_FALSE(channel_allocator_->IsPsmUsed(psm)); + } + + os::Thread* thread_{nullptr}; + os::Handler* handler_{nullptr}; + NiceMock* mock_parameter_provider_{nullptr}; + NiceMock* mock_classic_link_{nullptr}; + std::unique_ptr channel_allocator_; +}; + +} // namespace internal +} // namespace classic +} // namespace l2cap +} // namespace bluetooth + +void RunL2capClassicDynamicChannelAllocatorFuzzTest(const uint8_t* data, size_t size) { + bluetooth::l2cap::classic::internal::L2capClassicDynamicChannelAllocatorFuzzTest test; + test.RunTests(data, size); +} \ No newline at end of file diff --git a/system/gd/l2cap/classic/internal/link_mock.h b/system/gd/l2cap/classic/internal/link_mock.h index 710cc44801..58dbd55c2d 100644 --- a/system/gd/l2cap/classic/internal/link_mock.h +++ b/system/gd/l2cap/classic/internal/link_mock.h @@ -36,6 +36,10 @@ class MockLink : public Link { explicit MockLink(os::Handler* handler, l2cap::internal::ParameterProvider* parameter_provider) : Link(handler, std::make_unique(), std::make_unique(), parameter_provider, nullptr, nullptr){}; + explicit MockLink(os::Handler* handler, l2cap::internal::ParameterProvider* parameter_provider, + std::unique_ptr acl_connection, + std::unique_ptr scheduler) + : Link(handler, std::move(acl_connection), std::move(scheduler), parameter_provider, nullptr, nullptr){}; MOCK_METHOD(hci::Address, GetDevice, (), (override)); MOCK_METHOD(void, OnAclDisconnected, (hci::ErrorCode status), (override)); MOCK_METHOD(void, Disconnect, (), (override)); -- cgit v1.2.3-59-g8ed1b