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

Commit be274c3b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "DO NOT MERGE Ensure hci command status event has sufficient packet length" into qt-qpr1-dev

parents cbbc66ac b6eaa507
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -77,3 +77,39 @@ cc_test {
        "libbt-protos-lite",
    ],
}

// HCI native unit tests for target
// ========================================================
cc_test {
    name: "net_test_hci_native",
    test_suites: ["device-tests"],
    defaults: ["fluoride_defaults"],
    host_supported: true,
    local_include_dirs: [
        "include",
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/stack/include",
    ],
    srcs: [
        "test/hci_layer_test.cc",
        "test/other_stack_stub.cc",
    ],
    shared_libs: [
        "libcrypto",
        "liblog",
        "libprotobuf-cpp-lite",
    ],
    static_libs: [
        "libbt-common",
        "libbt-protos-lite",
        "libosi",
        "libosi-AllocationTestHarness",
    ],
    sanitize: {
        address: true,
        cfi: true,
        misc_undefined: ["bounds"],
    },
}
+7 −1
Original line number Diff line number Diff line
@@ -569,11 +569,12 @@ static bool filter_incoming_event(BT_HDR* packet) {
  waiting_command_t* wait_entry = NULL;
  uint8_t* stream = packet->data;
  uint8_t event_code;
  uint8_t length;
  int credits = 0;
  command_opcode_t opcode;

  STREAM_TO_UINT8(event_code, stream);
  STREAM_SKIP_UINT8(stream);  // Skip the parameter total length field
  STREAM_TO_UINT8(length, stream);

  if (event_code == HCI_COMMAND_COMPLETE_EVT) {
    STREAM_TO_UINT8(credits, stream);
@@ -601,6 +602,11 @@ static bool filter_incoming_event(BT_HDR* packet) {

    goto intercepted;
  } else if (event_code == HCI_COMMAND_STATUS_EVT) {
    if (length < (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint16_t))) {
      LOG_WARN(LOG_TAG, "%s Unexpected hci command status event length:%hhd",
               __func__, length);
      goto intercepted;
    }
    uint8_t status;
    STREAM_TO_UINT8(status, stream);
    STREAM_TO_UINT8(credits, stream);
+124 −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.
 */

#include <base/logging.h>
#include <gtest/gtest.h>
#include <stdint.h>

#include "common/message_loop_thread.h"
#include "hci/src/hci_layer.cc"
#include "hci_internals.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "osi/test/AllocationTestHarness.h"
#include "osi/test/test_stubs.h"
#include "stack/include/bt_types.h"
#include "stack/include/hcidefs.h"

extern void allocation_tracker_uninit(void);

allocator_t buffer_allocator_ = {
    .alloc = osi_malloc,
    .free = osi_free,
};

void monitor_socket(int ctrl_fd, int fd) {
  LOG(INFO) << __func__ << " UNIMPLEMENTED";
}
void hci_initialize() { LOG(INFO) << __func__ << " UNIMPLEMENTED"; }
void hci_close() { LOG(INFO) << __func__ << " UNIMPLEMENTED"; }
void hci_transmit(BT_HDR* packet) { LOG(INFO) << __func__ << " UNIMPLEMENTED"; }
int hci_open_firmware_log_file() { return INVALID_FD; }
void hci_close_firmware_log_file(int fd) {}
void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) {}
const allocator_t* buffer_allocator_get_interface() {
  return &buffer_allocator_;
}

/**
 * Test class to test selected functionality in hci/src/hci_layer.cc
 */
class HciLayerTest : public AllocationTestHarness {
 protected:
  void SetUp() override {
    AllocationTestHarness::SetUp();
    // Disable our allocation tracker to allow ASAN full range
    allocation_tracker_uninit();
    commands_pending_response = list_new(NULL);
    buffer_allocator = &buffer_allocator_;
  }

  void TearDown() override {
    list_free(commands_pending_response);
    AllocationTestHarness::TearDown();
  }

  BT_HDR* AllocateHciEventPacket(size_t packet_length) const {
    return AllocatePacket(packet_length, MSG_HC_TO_STACK_HCI_EVT);
  }

  uint8_t* GetPayloadPointer(BT_HDR* packet) const {
    return static_cast<uint8_t*>(packet->data);
  }

 private:
  BT_HDR* AllocatePacket(size_t packet_length, uint16_t event) const {
    BT_HDR* packet =
        static_cast<BT_HDR*>(osi_calloc(sizeof(BT_HDR) + packet_length));
    packet->offset = 0;
    packet->len = packet_length;
    packet->layer_specific = 0;
    packet->event = MSG_HC_TO_STACK_HCI_EVT;
    return packet;
  }
};

TEST_F(HciLayerTest, FilterIncomingEvent) {
  {
    BT_HDR* packet = AllocateHciEventPacket(3);

    auto p = GetPayloadPointer(packet);
    *p++ = HCI_COMMAND_STATUS_EVT;
    *p++ = 0x0;  // length

    CHECK(filter_incoming_event(packet));
  }

  {
    BT_HDR* packet = AllocateHciEventPacket(3);

    auto p = GetPayloadPointer(packet);
    *p++ = HCI_COMMAND_STATUS_EVT;
    *p++ = 0x1;  // length
    *p++ = 0xff;

    CHECK(filter_incoming_event(packet));
  }

  {
    BT_HDR* packet = AllocateHciEventPacket(6);

    auto p = GetPayloadPointer(packet);
    *p++ = HCI_COMMAND_STATUS_EVT;
    *p++ = 0x04;  // length
    *p++ = 0x00;  // status
    *p++ = 0x01;  // credits
    *p++ = 0x34;  // opcode0
    *p++ = 0x12;  // opcode1

    CHECK(filter_incoming_event(packet));
  }
}
+45 −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.
 */

/**
 * Gabeldorsche related legacy-only-stack-side expansion and support code.
 */
#include "base/bind.h"
#include "btcore/include/module.h"  // base::OnceClosure
#include "hci/include/btsnoop.h"
#include "hci/include/hci_layer.h"

const btsnoop_t* btsnoop_get_interface() { return nullptr; }
const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; }
base::MessageLoop* get_main_message_loop() { return nullptr; }

namespace bluetooth {
namespace bqr {

void DumpLmpLlMessage(uint8_t length, uint8_t* p_lmp_ll_message_event) {}
void DumpBtScheduling(unsigned char, unsigned char*) {}

}  // namespace bqr

namespace shim {

bool is_gd_shim_enabled() { return false; }
bool is_gd_stack_started_up() { return false; }
void Post(base::OnceClosure task) {}
const hci_t* hci_layer_get_interface() { return nullptr; }

}  // namespace shim
}  // namespace bluetooth