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

Commit 22cdcc3e authored by Dylan Katz's avatar Dylan Katz
Browse files

Adds fuzzer for l2cap



This adds a fuzzer for l2cap and a few related subcomponents.
Test: gd/fuzz/run bluetooth_gd_l2cap_fuzzer
Tag: #feature
Bug: 167425311
Sponsor: zachoverflow@

Signed-off-by: default avatarDylan Katz <dylan.katz@leviathansecurity.com>
Change-Id: I052f103929749b6532c66881cf88589375cf8a5d
parent fcc85925
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
cc_fuzz {
    name: "bluetooth_gd_l2cap_fuzzer",
    defaults: ["gd_fuzz_defaults"],
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/gd",
        "packages/modules/Bluetooth/system/bta/include",
        "packages/modules/Bluetooth/system/bta/sys",
        "packages/modules/Bluetooth/system/bta/dm",
        "packages/modules/Bluetooth/system/btcore/include",
        "packages/modules/Bluetooth/system/internal_include",
        "packages/modules/Bluetooth/system/stack/include",
        "packages/modules/Bluetooth/system/stack/l2cap",
        "packages/modules/Bluetooth/system/stack/a2dp",
        "packages/modules/Bluetooth/system/stack/btm",
        "packages/modules/Bluetooth/system/stack/avdt",
        "packages/modules/Bluetooth/system/udrv/include",
        "packages/modules/Bluetooth/system/btif/include",
        "packages/modules/Bluetooth/system/btif/co",
        "packages/modules/Bluetooth/system/hci/include",
        "packages/modules/Bluetooth/system/vnd/include",
        "packages/modules/Bluetooth/system/embdrv/sbc/encoder/include",
        "packages/modules/Bluetooth/system/embdrv/sbc/decoder/include",
        "packages/modules/Bluetooth/system/utils/include",
        "system/security/keystore/include",
        "hardware/interfaces/keymaster/4.0/support/include",
    ],
    srcs: [
        "channel_fuzz_controller.cc",
        "fuzz_l2cap.cc",
    ],
    static_libs: [
        "libbte",
    ],
}
+40 −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.
 */
// Authors: corbin.souffrant@leviathansecurity.com
//          dylan.katz@leviathansecurity.com

#include "channel_fuzz_controller.h"

namespace bluetooth {
using l2cap::classic::internal::FixedChannelImpl;
using l2cap::internal::DynamicChannelImpl;
using os::Handler;

ChannelFuzzController::ChannelFuzzController(Handler* l2cap_handler, std::shared_ptr<DynamicChannelImpl> chan) {
  EnqueueType* queue = reinterpret_cast<EnqueueType*>(chan->GetQueueUpEnd());
  channelInject_ = std::make_shared<ChannelFuzzQueueType>(queue, l2cap_handler);
}

ChannelFuzzController::ChannelFuzzController(Handler* l2cap_handler, std::shared_ptr<FixedChannelImpl> chan) {
  EnqueueType* queue = reinterpret_cast<EnqueueType*>(chan->GetQueueUpEnd());
  channelInject_ = std::make_shared<ChannelFuzzQueueType>(queue, l2cap_handler);
}

void ChannelFuzzController::injectFrame(std::vector<uint8_t> data) {
  CONSTRUCT_VALID_UNIQUE_OTHERWISE_BAIL(l2cap::BasicFrameView, packet, data);
  channelInject_->Inject(std::move(packet));
}
}  // namespace bluetooth
+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.
 */
// Authors: corbin.souffrant@leviathansecurity.com
//          dylan.katz@leviathansecurity.com

#pragma once
#include "gd/fuzz/helpers.h"
#include "l2cap/classic/internal/fixed_channel_impl.h"
#include "l2cap/internal/dynamic_channel_impl.h"
#include "l2cap/l2cap_packets.h"
#include "os/fuzz/fuzz_inject_queue.h"
#include "os/handler.h"
#include "packet/packet_view.h"

namespace bluetooth {

typedef os::IQueueEnqueue<packet::PacketView<packet::kLittleEndian>> EnqueueType;
typedef os::fuzz::FuzzInjectQueue<packet::PacketView<packet::kLittleEndian>> ChannelFuzzQueueType;

class ChannelFuzzController {
 public:
  ChannelFuzzController(os::Handler* l2cap_handler, std::shared_ptr<l2cap::internal::DynamicChannelImpl> chan);

  ChannelFuzzController(os::Handler* l2cap_handler, std::shared_ptr<l2cap::classic::internal::FixedChannelImpl> chan);

  void injectPacketData(std::vector<uint8_t> data);

  void injectFrame(std::vector<uint8_t> data);

 private:
  std::shared_ptr<ChannelFuzzQueueType> channelInject_;
};
}  // namespace bluetooth
+63 −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.
 */
// Authors: corbin.souffrant@leviathansecurity.com
//          dylan.katz@leviathansecurity.com

#pragma once

#include <gd/l2cap/classic/dynamic_channel_service.h>
#include <gd/l2cap/classic/internal/dynamic_channel_service_impl.h>
#include <gd/l2cap/classic/internal/dynamic_channel_service_manager_impl.h>
#include <memory>

#include "hci/address.h"
#include "l2cap/classic/dynamic_channel_configuration_option.h"
#include "l2cap/classic/dynamic_channel_manager.h"
#include "l2cap/classic/security_policy.h"
#include "l2cap/psm.h"
#include "os/handler.h"

#include "fuzz_dynamic_channel_manager_impl.h"

namespace bluetooth {
namespace shim {
namespace {
class FuzzDynamicChannelManager : public l2cap::classic::DynamicChannelManager {
 public:
  void ConnectChannel(
      hci::Address device,
      l2cap::classic::DynamicChannelConfigurationOption configuration_option,
      l2cap::Psm psm,
      l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,
      l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback) override {
    impl_.ConnectChannel(device, configuration_option, psm, std::move(on_open_callback), std::move(on_fail_callback));
  }

  void RegisterService(
      l2cap::Psm psm,
      l2cap::classic::DynamicChannelConfigurationOption configuration_option,
      const l2cap::classic::SecurityPolicy& security_policy,
      l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,
      l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback) override {
    impl_.RegisterService(
        psm, configuration_option, security_policy, std::move(on_registration_complete), std::move(on_open_callback));
  }
  FuzzDynamicChannelManager(FuzzDynamicChannelManagerImpl& impl) : impl_(impl) {}
  FuzzDynamicChannelManagerImpl& impl_;
};
}  // namespace
}  // namespace shim
}  // namespace bluetooth
+110 −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.
 */
// Authors: corbin.souffrant@leviathansecurity.com
//          dylan.katz@leviathansecurity.com

#pragma once

#include <gd/l2cap/classic/internal/dynamic_channel_service_manager_impl.h>
#include <gd/shim/l2cap.h>
#include <future>
#include <memory>

#include "hci/address.h"
#include "l2cap/classic/dynamic_channel_configuration_option.h"
#include "l2cap/classic/dynamic_channel_manager.h"
#include "l2cap/classic/security_policy.h"
#include "l2cap/psm.h"
#include "os/handler.h"

namespace bluetooth {
namespace shim {
namespace {
class FuzzDynamicChannelManagerImpl {
 public:
  void ConnectChannel(
      hci::Address device,
      l2cap::classic::DynamicChannelConfigurationOption configuration_option,
      l2cap::Psm,
      l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback,
      l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback) {
    connections_++;
    on_open_callback_ = std::move(on_open_callback);
    on_fail_callback_ = std::move(on_fail_callback);

    connected_promise_.set_value();
  }
  int connections_{0};

  void RegisterService(
      l2cap::Psm,
      l2cap::classic::DynamicChannelConfigurationOption,
      const l2cap::classic::SecurityPolicy&,
      l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,
      l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback) {
    services_++;
    on_registration_complete_ = std::move(on_registration_complete);
    on_open_callback_ = std::move(on_open_callback);

    register_promise_.set_value();
  }
  int services_{0};

  void SetConnectionFuture() {
    connected_promise_ = std::promise<void>();
  }

  void WaitConnectionFuture() {
    connected_future_ = connected_promise_.get_future();
    connected_future_.wait();
  }

  void SetRegistrationFuture() {
    register_promise_ = std::promise<void>();
  }

  void WaitRegistrationFuture() {
    register_future_ = register_promise_.get_future();
    register_future_.wait();
  }

  void SetConnectionOnFail(l2cap::classic::DynamicChannelManager::ConnectionResult result, std::promise<void> promise) {
    std::move(on_fail_callback_).Invoke(result);
    promise.set_value();
  }

  void SetConnectionOnOpen(std::unique_ptr<l2cap::DynamicChannel> channel, std::promise<void> promise) {
    std::move(on_open_callback_).Invoke(std::move(channel));
    promise.set_value();
  }

  l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete_{};
  l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_open_callback_{};
  l2cap::classic::DynamicChannelManager::OnConnectionFailureCallback on_fail_callback_{};

  FuzzDynamicChannelManagerImpl() = default;
  ~FuzzDynamicChannelManagerImpl() = default;

 private:
  std::promise<void> connected_promise_;
  std::future<void> connected_future_;

  std::promise<void> register_promise_;
  std::future<void> register_future_;
};
}  // namespace
}  // namespace shim
}  // namespace bluetooth
Loading