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

Commit 9e2686b5 authored by Michael Ensing's avatar Michael Ensing
Browse files

Add A2DP/SDP fuzzers for bt-stack



Added Libfuzzer fuzzers for both the A2DP and SDP components of
bt-stack. Fuzzers will call exposed API functions with random
order/parameters. Note that as some of these components fight with
libfuzzer for signal handlers, it's recommended to run these with
the following env_vars:
  HWASAN_OPTIONS='handle_abort=2 handle_segv=1 allocator_may_return_null=1'

Test: Tested each fuzzer for a few million iterations without
      fuzzer-side crashes. Execs/s are approximately in the 50-250
      range after coverage is established (all fuzzers running on a
      single device).
Signed-off-by: default avatarMichael Ensing <michael.ensing@leviathansecurity.com>
Change-Id: Ib40c39fd4bc77a97310ee0e550b19bafbbb7057e
parent fd6dc571
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
cc_defaults {
    name: "libbt-stack_fuzz_defaults",
    defaults: ["fluoride_defaults"],
    include_dirs: [
        "packages/modules/Bluetooth/system/",
        "packages/modules/Bluetooth/system/include/",
        "packages/modules/Bluetooth/system/types/",
        "packages/modules/Bluetooth/system/internal_include/",
        "packages/modules/Bluetooth/system/stack/include",
        "packages/modules/Bluetooth/system/stack/test",
    ],
    static_libs: [
        "libbt-stack",
        "libbte",
        "libFraunhoferAAC",
        "libbt-audio-hal-interface",
        "libbtcore",
        "libbt-bta",
        "libbt-stack",
        "libbt-common",
        "libbt-sbc-decoder",
        "libbt-sbc-encoder",
        "libbt-utils",
        "libbtif",
        "libbt-hci",
        "libbtdevice",
        "libg722codec",
        "libosi",
        "libudrv-uipc",
        "libbt-protos-lite",
        "libbluetooth_gd",
    ],
    shared_libs: [
        "libbinder",
        "libbase",
        "libcutils",
        "liblog",
        "android.hardware.bluetooth@1.0",
        "android.hardware.bluetooth@1.1",
        "android.hardware.bluetooth.a2dp@1.0",
        "android.hardware.bluetooth.audio@2.0",
        "libaaudio",
        "libfmq",
        "libhidlbase",
        "libprocessgroup",
        "libprotobuf-cpp-lite",
        "libutils",
        "libcrypto",
    ],
}
+7 −0
Original line number Diff line number Diff line
cc_fuzz {
    name: "a2dp_fuzz",
    defaults: ["libbt-stack_fuzz_defaults"],
    srcs: [
        "fuzz_a2dp.cc",
    ],
}
+90 −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.
 */

#ifndef BT_STACK_FUZZ_A2DP_FUNCTIONS_H_
#define BT_STACK_FUZZ_A2DP_FUNCTIONS_H_

#include <fuzzer/FuzzedDataProvider.h>
#include <vector>
#include "a2dp_api.h"
#include "osi/include/allocator.h"
#include "raw_address.h"
#include "stack/a2dp/a2dp_int.h"

#include "fuzzers/a2dp/a2dpFuzzHelpers.h"
#include "fuzzers/common/commonFuzzHelpers.h"
#include "fuzzers/sdp/sdpFuzzFunctions.h"

#define MAX_STR_LEN 4096

/* This is a vector of lambda functions the fuzzer will pull from.
 *  This is done so new functions can be added to the fuzzer easily
 *  without requiring modifications to the main fuzzer file. This also
 *  allows multiple fuzzers to include this file, if functionality is needed.
 */
std::vector<std::function<void(FuzzedDataProvider*)>> a2dp_operations = {
    // Init
    [](FuzzedDataProvider*) -> void {
      // Re-init zeros out memory containing some pointers.
      // Free the db first to prevent memleaks
      if (a2dp_cb.find.p_db) {
        osi_free(a2dp_cb.find.p_db);
      }

      // Attempt re-initializations mid-run.
      A2DP_Init();
    },

    // A2DP_AddRecord
    [](FuzzedDataProvider* fdp) -> void {
      std::vector<char> p_service_name =
          fdp->ConsumeBytesWithTerminator<char>(MAX_STR_LEN);
      std::vector<char> p_provider_name =
          fdp->ConsumeBytesWithTerminator<char>(MAX_STR_LEN);
      A2DP_AddRecord(fdp->ConsumeIntegral<uint16_t>(), p_service_name.data(),
                     p_provider_name.data(), fdp->ConsumeIntegral<uint16_t>(),
                     // This should be a val returned by SDP_CreateRecord
                     getArbitraryVectorElement(fdp, sdp_record_handles, true));
    },

    // A2DP_FindService
    [](FuzzedDataProvider* fdp) -> void {
      tA2DP_SDP_DB_PARAMS p_db = generateDBParams(fdp);
      const RawAddress bd_addr = generateRawAddress(fdp);
      A2DP_FindService(fdp->ConsumeIntegral<uint16_t>(), bd_addr, &p_db,
                       a2dp_find_callback);
    },

    // A2DP_GetAvdtpVersion
    [](FuzzedDataProvider*) -> void { A2DP_GetAvdtpVersion(); },

    // A2DP_SetTraceLevel
    [](FuzzedDataProvider* fdp) -> void {
      // Expected val is [0-5], 0xff but other values are supported so fuzz all
      A2DP_SetTraceLevel(fdp->ConsumeIntegral<uint8_t>());
    },

    // A2DP_BitsSet
    [](FuzzedDataProvider* fdp) -> void {
      A2DP_BitsSet(fdp->ConsumeIntegral<uint64_t>());
    },

    // SDP Calls
    [](FuzzedDataProvider* fdp) -> void {
      callArbitraryFunction(fdp, sdp_operations);
    }};

#endif  // BT_STACK_FUZZ_A2DP_FUNCTIONS_H_
+64 −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.
 */

#ifndef BT_STACK_FUZZ_A2DP_HELPERS_H_
#define BT_STACK_FUZZ_A2DP_HELPERS_H_

// NOTE: This file should not be included directly.
//       It is included by the corresponding "...Functions.h" file.

#include <fuzzer/FuzzedDataProvider.h>
#include <vector>
#include "bt_target.h"
#include "bt_trace.h"
#include "fuzzers/sdp/sdpFuzzHelpers.h"
#include "osi/include/allocator.h"
#include "stack/a2dp/a2dp_int.h"

#define MAX_DB_SIZE 4096

tA2DP_SDP_DB_PARAMS generateDBParams(FuzzedDataProvider* fdp) {
  std::vector<uint16_t> attr_list = generateArbitraryAttrList(fdp);

  tA2DP_SDP_DB_PARAMS db_params;
  db_params.db_len = fdp->ConsumeIntegralInRange<uint32_t>(0, MAX_DB_SIZE);
  db_params.num_attr = attr_list.size();
  db_params.p_attrs = attr_list.empty() ? nullptr : attr_list.data();

  return db_params;
}

// Define our empty callback function
void a2dp_find_callback(bool found, tA2DP_Service* p_service,
                        const RawAddress& peer_address) {
  // Free the RawAddress we created in the generate function
  delete &peer_address;
}

// Function to clean up and clear our allocated objects
void cleanupA2dpFuzz() {
  // Delete our a2dp_cb database if it exists
  if (a2dp_cb.find.p_db) {
    osi_free(a2dp_cb.find.p_db);
  }
  // This function resets the a2dp_cb global to defaults
  A2DP_Init();

  // SDP needs to perform cleanup as well.
  cleanupSdpFuzz();
}

#endif  // BT_STACK_FUZZ_A2DP_HELPERS_H_
+32 −0
Original line number Diff line number Diff line
cc_defaults {
    name: "libbt-stack_fuzz_codec_defaults",
    defaults: ["libbt-stack_fuzz_defaults"],
    include_dirs: [
        "packages/modules/Bluetooth/system/bta/include/", // For tBT_A2DP_OFFLOAD
        "packages/modules/Bluetooth/system/bta/sys/", // For tBT_A2DP_OFFLOAD
    ],
}

cc_fuzz {
    name: "a2dp_codec_fuzz",
    defaults: ["libbt-stack_fuzz_codec_defaults"],
    srcs: [
        "fuzz_a2dp_codec.cc",
    ],
}

cc_fuzz {
    name: "a2dp_codec_info_fuzz",
    defaults: ["libbt-stack_fuzz_codec_defaults"],
    srcs: [
        "fuzz_a2dp_codec_info.cc",
    ],
}

cc_fuzz {
    name: "a2dp_codec_cfg_fuzz",
    defaults: ["libbt-stack_fuzz_codec_defaults"],
    srcs: [
        "fuzz_a2dp_codec_config.cc",
    ],
}
Loading