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

Commit c0cffb79 authored by Jack He's avatar Jack He
Browse files

Add FUZZ test generator for packets and L2CAP fuzz tests

* Add fuzz test generator for packet generator to generate macros for
  fuzz tests
* Add a few fuzz tests for L2CAP packets

Bug: 142684649
Test: bluetooth_gd_fuzz_test
Change-Id: I75bf726b40caef3c7895596039d01c395d34506f
parent 3e47b9ea
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,8 +18,10 @@
#include <stdint.h>

extern void RunL2capClassicDynamicChannelAllocatorFuzzTest(const uint8_t* data, size_t size);
extern void RunL2capPacketFuzzTest(const uint8_t* data, size_t size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  RunL2capClassicDynamicChannelAllocatorFuzzTest(data, size);
  RunL2capPacketFuzzTest(data, size);
  return 0;
}
 No newline at end of file
+1 −0
Original line number Diff line number Diff line
@@ -66,5 +66,6 @@ filegroup {
    name: "BluetoothL2capFuzzTestSources",
    srcs: [
        "classic/internal/dynamic_channel_allocator_fuzz_test.cc",
        "l2cap_packet_fuzz_test.cc",
    ],
}
+55 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#define PACKET_FUZZ_TESTING
#include "l2cap/l2cap_packets.h"

#include <gtest/gtest.h>
#include <forward_list>
#include <memory>

#include "os/log.h"
#include "packet/bit_inserter.h"
#include "packet/raw_builder.h"

using bluetooth::packet::BitInserter;
using bluetooth::packet::RawBuilder;
using std::vector;

namespace bluetooth {
namespace l2cap {

DEFINE_ExtendedInformationStartFrameReflectionFuzzTest;

DEFINE_StandardInformationFrameWithFcsReflectionFuzzTest;

DEFINE_StandardSupervisoryFrameWithFcsReflectionFuzzTest;

DEFINE_GroupFrameReflectionFuzzTest;

DEFINE_ConfigurationRequestReflectionFuzzTest;

}  // namespace l2cap
}  // namespace bluetooth

void RunL2capPacketFuzzTest(const uint8_t* data, size_t size) {
  if (data == nullptr) return;
  bluetooth::l2cap::RunExtendedInformationStartFrameReflectionFuzzTest(data, size);
  bluetooth::l2cap::RunStandardInformationFrameWithFcsReflectionFuzzTest(data, size);
  bluetooth::l2cap::RunStandardSupervisoryFrameWithFcsReflectionFuzzTest(data, size);
  bluetooth::l2cap::RunGroupFrameReflectionFuzzTest(data, size);
  bluetooth::l2cap::RunConfigurationRequestReflectionFuzzTest(data, size);
}
 No newline at end of file
+41 −0
Original line number Diff line number Diff line
@@ -285,6 +285,9 @@ void PacketDef::GenBuilderDefinition(std::ostream& s) const {

  GenTestDefine(s);
  s << "\n";

  GenFuzzTestDefine(s);
  s << "\n";
}

void PacketDef::GenTestDefine(std::ostream& s) const {
@@ -336,6 +339,44 @@ void PacketDef::GenTestDefine(std::ostream& s) const {
  s << "\n#endif";
}

void PacketDef::GenFuzzTestDefine(std::ostream& s) const {
  s << "#ifdef PACKET_FUZZ_TESTING\n";
  s << "#define DEFINE_" << name_ << "ReflectionFuzzTest ";
  s << "void Run" << name_ << "ReflectionFuzzTest(const uint8_t* data, size_t size) {";
  s << "auto vec = std::make_shared<std::vector<uint8_t>>(data, data + size);";
  s << name_ << "View view = " << name_ << "View::Create(";
  auto ancestor_ptr = parent_;
  size_t parent_parens = 0;
  while (ancestor_ptr != nullptr) {
    s << ancestor_ptr->name_ << "View::Create(";
    parent_parens++;
    ancestor_ptr = ancestor_ptr->parent_;
  }
  s << "vec";
  for (size_t i = 0; i < parent_parens; i++) {
    s << ")";
  }
  s << ");";
  s << "if (!view.IsValid()) { return; }";
  s << "auto packet = " << name_ << "Builder::Create(";
  FieldList params = GetParamList().GetFieldsWithoutTypes({
      BodyField::kFieldType,
  });
  for (int i = 0; i < params.size(); i++) {
    params[i]->GenBuilderParameterFromView(s);
    if (i != params.size() - 1) {
      s << ", ";
    }
  }
  s << ");";
  s << "std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();";
  s << "packet_bytes->reserve(packet->size());";
  s << "BitInserter it(*packet_bytes);";
  s << "packet->Serialize(it);";
  s << "}";
  s << "\n#endif";
}

FieldList PacketDef::GetParametersToValidate() const {
  FieldList params_to_validate;
  for (const auto& field : GetParamList()) {
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ class PacketDef : public ParentDef {

  void GenTestDefine(std::ostream& s) const;

  void GenFuzzTestDefine(std::ostream& s) const;

  FieldList GetParametersToValidate() const;

  void GenBuilderCreate(std::ostream& s) const;