Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cab7cf5 authored by Zach Johnson's avatar Zach Johnson
Browse files

Add fuzzer concepts to inject builders into a layer

Test: fuzz/run --host bluetooth_gd_hci_fuzz_test
Change-Id: Ie1b46fc24b3a639aaf388ad36d80a8ef73c1fff9
parent 639860bd
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@
#include "hci/hci_packets.h"
#include "module.h"
#include "os/fuzz/dev_null_queue.h"
#include "os/fuzz/fuzz_inject_queue.h"

using bluetooth::hci::AclPacketView;
using bluetooth::hci::HciLayer;
using bluetooth::os::fuzz::DevNullQueue;
using bluetooth::os::fuzz::FuzzInjectQueue;

namespace bluetooth {
namespace hci {
@@ -37,11 +39,23 @@ class DevNullHci : public Module {
    hci_ = GetDependency<HciLayer>();
    aclDevNull_ = new DevNullQueue<AclPacketView>(hci_->GetAclQueueEnd(), GetHandler());
    aclDevNull_->Start();
    aclInject_ = new FuzzInjectQueue<AclPacketBuilder>(hci_->GetAclQueueEnd(), GetHandler());
  }

  void Stop() override {
    aclDevNull_->Stop();
    delete aclDevNull_;
    delete aclInject_;
  }

  void injectAclData(std::vector<uint8_t> data) {
    auto packet = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(data));
    hci::AclPacketView aclPacket = hci::AclPacketView::Create(packet);
    if (!aclPacket.IsValid()) {
      return;
    }

    aclInject_->Inject(AclPacketBuilder::FromView(aclPacket));
  }

  void ListDependencies(ModuleList* list) override {
@@ -57,6 +71,7 @@ class DevNullHci : public Module {
 private:
  HciLayer* hci_ = nullptr;
  DevNullQueue<AclPacketView>* aclDevNull_;
  FuzzInjectQueue<AclPacketBuilder>* aclInject_;
};

const ModuleFactory DevNullHci::Factory = ModuleFactory([]() { return new DevNullHci(); });
+5 −1
Original line number Diff line number Diff line
@@ -40,9 +40,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {

  moduleRegistry.InjectTestModule(&HciHal::Factory, fuzzHal);
  moduleRegistry.Start<DevNullHci>(&moduleRegistry.GetTestThread());
  DevNullHci* devNullHci = moduleRegistry.GetModuleUnderTest<DevNullHci>();

  while (dataProvider.remaining_bytes() > 0) {
    const uint8_t action = dataProvider.ConsumeIntegralInRange(0, 4);
    const uint8_t action = dataProvider.ConsumeIntegralInRange(0, 5);
    switch (action) {
      case 1:
        fake_timerfd_advance(dataProvider.ConsumeIntegral<uint64_t>());
@@ -56,6 +57,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
      case 4:
        fuzzHal->injectScoData(dataProvider.ConsumeBytes<uint8_t>(dataProvider.ConsumeIntegral<size_t>()));
        break;
      case 5:
        devNullHci->injectAclData(dataProvider.ConsumeBytes<uint8_t>(dataProvider.ConsumeIntegral<size_t>()));
        break;
    }
  }

+5 −0
Original line number Diff line number Diff line
@@ -161,6 +161,11 @@ class TestModuleRegistry : public ModuleRegistry {
    return Get(module);
  }

  template <class T>
  T* GetModuleUnderTest() const {
    return static_cast<T*>(GetModuleUnderTest(&T::Factory));
  }

  os::Handler* GetTestModuleHandler(const ModuleFactory* module) const {
    return GetModuleHandler(module);
  }
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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

#include "os/queue.h"

namespace bluetooth {
namespace os {
namespace fuzz {

template <typename T>
class FuzzInjectQueue {
 public:
  FuzzInjectQueue(IQueueEnqueue<T>* queue, Handler* handler) : handler_(handler) {
    buffer_ = new EnqueueBuffer<T>(queue);
  }
  ~FuzzInjectQueue() {
    delete buffer_;
  }

  void Inject(std::unique_ptr<T> data) {
    buffer_->Enqueue(std::move(data), handler_);
  }

 private:
  EnqueueBuffer<T>* buffer_;
  Handler* handler_;
};

}  // namespace fuzz
}  // namespace os
}  // namespace bluetooth
+4 −0
Original line number Diff line number Diff line
@@ -95,3 +95,7 @@ void CustomField::GenValidator(std::ostream&) const {
void CustomField::GenStringRepresentation(std::ostream& s, std::string accessor) const {
  s << accessor << "->ToString()";
}

void CustomField::GenBuilderParameterFromView(std::ostream& s) const {
  s << "*view.Get" << util::UnderscoreToCamelCase(GetName()) << "()";
}
Loading