Check a2dp packet length is zero
Bug: 142546668
Test: net_test_stack_a2dp_native
Change-Id: I105b445293c02cb4f37c759fd5b05758fd4e3646
Merged-In: I105b445293c02cb4f37c759fd5b05758fd4e3646
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 5f6e378..d29c2f7 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -76,6 +76,10 @@
{
"name" : "net_test_types",
"host" : true
+ },
+ {
+ "name" : "net_test_stack_a2dp_native",
+ "host" : true
}
]
}
diff --git a/stack/Android.bp b/stack/Android.bp
index f7f5a45..4863afb 100644
--- a/stack/Android.bp
+++ b/stack/Android.bp
@@ -446,3 +446,36 @@
cfi: false,
},
}
+
+cc_test {
+ name: "net_test_stack_a2dp_native",
+ defaults: ["fluoride_defaults"],
+ test_suites: ["device-tests"],
+ host_supported: true,
+ include_dirs: [
+ "external/libldac/inc",
+ "system/bt",
+ "system/bt/stack/include",
+ ],
+ srcs: [
+ "test/a2dp/a2dp_vendor_ldac_decoder_test.cc",
+ "test/a2dp/misc_fake.cc",
+ ],
+ shared_libs: [
+ "libcrypto",
+ "libcutils",
+ "libprotobuf-cpp-lite",
+ ],
+ static_libs: [
+ "libbt-common",
+ "libbt-protos-lite",
+ "liblog",
+ "libosi",
+ "libosi-AllocationTestHarness",
+ ],
+ sanitize: {
+ address: true,
+ cfi: true,
+ misc_undefined: ["bounds"],
+ },
+}
diff --git a/stack/a2dp/a2dp_vendor_ldac_decoder.cc b/stack/a2dp/a2dp_vendor_ldac_decoder.cc
index 444af34..d49337a 100644
--- a/stack/a2dp/a2dp_vendor_ldac_decoder.cc
+++ b/stack/a2dp/a2dp_vendor_ldac_decoder.cc
@@ -217,11 +217,20 @@
}
bool a2dp_vendor_ldac_decoder_decode_packet(BT_HDR* p_buf) {
+ if (p_buf == nullptr) {
+ LOG_ERROR(LOG_TAG, "%s Dropping packet with nullptr", __func__);
+ return false;
+ }
unsigned char* pBuffer =
reinterpret_cast<unsigned char*>(p_buf->data + p_buf->offset);
// unsigned int bufferSize = p_buf->len;
unsigned int bytesValid = p_buf->len;
int err;
+ if (bytesValid == 0) {
+ LOG_WARN(LOG_TAG, "%s Dropping packet with zero length", __func__);
+ return false;
+ }
+
LDACBT_SMPL_FMT_T fmt;
int bs_bytes, used_bytes, wrote_bytes, frame_number;
diff --git a/stack/include/ldacBT_bco_for_fluoride.h b/stack/include/ldacBT_bco_for_fluoride.h
new file mode 100644
index 0000000..9666a7c
--- /dev/null
+++ b/stack/include/ldacBT_bco_for_fluoride.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2016 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 LDACBT_BCO_FOR_FLUORIDE_H__
+#define LDACBT_BCO_FOR_FLUORIDE_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef LDAC_BCO_API
+#define LDAC_BCO_API
+#endif /* LDAC_BCO_API */
+
+/* This file contains the definitions, declarations and macros for an
+ * implementation of LDAC buffer control operation.
+ */
+
+#define LDAC_BCO_ERR_NONE 0
+#define LDAC_BCO_ERR_FATAL (-1)
+
+/* LDAC BCO handle type */
+typedef struct _ldacbt_bco_handle* HANDLE_LDAC_BCO;
+
+typedef void (*decoded_data_callback_t)(uint8_t* buf, uint32_t len);
+
+/* Prepare to use LDAC BCO.
+ * - Register a callback function for passing decoded data.
+ * - Allocation of LDAC BCO handle.
+ * Format
+ * HANDLE_LDAC_BCO ldac_BCO_init(decoded_data_callback_t decode_callback);
+ * Arguments
+ * decoded_data_callback_t decode_callback
+ * Callback function that outputs PCM data after decoding.
+ * (See also a2dp_codec_api.h)
+ * Return value
+ * HANDLE_LDAC_BCO for success, NULL for failure.
+ */
+LDAC_BCO_API HANDLE_LDAC_BCO
+ldac_BCO_init(decoded_data_callback_t decode_callback);
+
+/* End LDAC BCO.
+ * - Release of LDAC BCO handle.
+ * Format
+ * int32_t ldac_BCO_cleanup(HANDLE_LDAC_BCO hLdacBco);
+ * Arguments
+ * HANDLE_LDAC_BCO hLdacBco LDAC BCO handle.
+ * Return value
+ * int32_t : Processing result.
+ * LDAC_BCO_ERR_NONE:Successful completion
+ * LDAC_BCO_ERR_FATAL:Error
+ * Note
+ * The function ldac_BCO_init() shall be called before calling this
+ * function.
+ */
+LDAC_BCO_API int32_t ldac_BCO_cleanup(HANDLE_LDAC_BCO hLdacBco);
+
+/* Decode LDAC packets.
+ * - Perform buffer control and decode processing.
+ * Format
+ * int32_t ldac_BCO_decode_packet(HANDLE_LDAC_BCO hLdacBco, void *data,
+ * int32_t length);
+ * Arguments
+ * HANDLE_LDAC_BCO hLdacBco LDAC BCO handle.
+ * void *data LDAC packet.
+ * int32_t length LDAC packet size.
+ * Return value
+ * int32_t : Processing result.
+ * LDAC_BCO_ERR_NONE:Successful completion
+ * LDAC_BCO_ERR_FATAL:Error
+ * Note
+ * The function ldac_BCO_init() shall be called before calling this
+ * function.
+ */
+LDAC_BCO_API int32_t ldac_BCO_decode_packet(HANDLE_LDAC_BCO hLdacBco,
+ void* data, int32_t length);
+
+/* Start decoding process.
+ * - Start or resume decoder thread.
+ * Format
+ * int32_t ldac_BCO_start(HANDLE_LDAC_BCO hLdacBco);
+ * Arguments
+ * HANDLE_LDAC_BCO hLdacBco LDAC BCO handle.
+ * Return value
+ * int32_t : Processing result.
+ * LDAC_BCO_ERR_NONE:Successful completion
+ * LDAC_BCO_ERR_FATAL:Error
+ * Note
+ * The function ldac_BCO_init() shall be called before calling this
+ * function.
+ */
+LDAC_BCO_API int32_t ldac_BCO_start(HANDLE_LDAC_BCO hLdacBco);
+
+/* Suspend decoding process.
+ * - Suspend the decoder thread.
+ * Format
+ * int32_t ldac_BCO_suspend(HANDLE_LDAC_BCO hLdacBco);
+ * Arguments
+ * HANDLE_LDAC_BCO hLdacBco LDAC BCO handle.
+ * Return value
+ * int32_t : Processing result.
+ * LDAC_BCO_ERR_NONE:Successful completion
+ * LDAC_BCO_ERR_FATAL:Error
+ * Note
+ * The function ldac_BCO_init() shall be called before calling this
+ * function.
+ */
+LDAC_BCO_API int32_t ldac_BCO_suspend(HANDLE_LDAC_BCO hLdacBco);
+
+/* Configure codec information.
+ * - Set sample rate, bits/sample and channel mode.
+ * Format
+ * int32_t ldac_BCO_configure(HANDLE_LDAC_BCO hLdacBco,
+ * int32_t sample_rate, int32_t bits_per_sample,
+ * int32_t channel_mode);
+ * Arguments
+ * HANDLE_LDAC_BCO hLdacBco LDAC BCO handle.
+ * int32_t sample_rate sample rate.
+ * int32_t bits_per_sample bits/sample.
+ * int32_t channel_mode channel mode.
+ * Return value
+ * int32_t : Processing result.
+ * LDAC_BCO_ERR_NONE:Successful completion
+ * LDAC_BCO_ERR_FATAL:Error
+ * Note
+ * The function ldac_BCO_init() shall be called before calling this
+ * function.
+ */
+LDAC_BCO_API int32_t ldac_BCO_configure(HANDLE_LDAC_BCO hLdacBco,
+ int32_t sample_rate,
+ int32_t bits_per_sample,
+ int32_t channel_mode);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LDACBT_BCO_FOR_FLUORIDE_H__ */
diff --git a/stack/test/a2dp/a2dp_vendor_ldac_decoder_test.cc b/stack/test/a2dp/a2dp_vendor_ldac_decoder_test.cc
new file mode 100644
index 0000000..ac8c260
--- /dev/null
+++ b/stack/test/a2dp/a2dp_vendor_ldac_decoder_test.cc
@@ -0,0 +1,68 @@
+/*
+ * 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 <stdio.h>
+#include <cstdint>
+
+#include "stack/include/ldacBT_bco_for_fluoride.h"
+
+#include "osi/test/AllocationTestHarness.h"
+#undef LOG_TAG
+#include "stack/a2dp/a2dp_vendor_ldac_decoder.cc"
+
+extern void allocation_tracker_uninit(void);
+namespace {
+
+uint8_t* Data(BT_HDR* packet) { return packet->data + packet->offset; }
+
+} // namespace
+
+/**
+ * Test class to test selected functionality in stack/a2dp
+ */
+class A2dpStackTest : public AllocationTestHarness {
+ protected:
+ void SetUp() override {
+ AllocationTestHarness::SetUp();
+ // Disable our allocation tracker to allow ASAN full range
+ allocation_tracker_uninit();
+ }
+
+ void TearDown() override { AllocationTestHarness::TearDown(); }
+
+ BT_HDR* AllocateL2capPacket(const std::vector<uint8_t> data) const {
+ auto packet = AllocatePacket(data.size());
+ std::copy(data.cbegin(), data.cend(), Data(packet));
+ return packet;
+ }
+
+ private:
+ BT_HDR* AllocatePacket(size_t packet_length) const {
+ BT_HDR* packet =
+ static_cast<BT_HDR*>(osi_calloc(sizeof(BT_HDR) + packet_length));
+ packet->len = packet_length;
+ return packet;
+ }
+};
+
+TEST_F(A2dpStackTest, DecodePacket_ZeroLength) {
+ const std::vector<uint8_t> data;
+ BT_HDR* p_buf = AllocateL2capPacket(data);
+ CHECK(!a2dp_vendor_ldac_decoder_decode_packet(p_buf));
+ osi_free(p_buf);
+}
diff --git a/stack/test/a2dp/misc_fake.cc b/stack/test/a2dp/misc_fake.cc
new file mode 100644
index 0000000..6f06218
--- /dev/null
+++ b/stack/test/a2dp/misc_fake.cc
@@ -0,0 +1,28 @@
+/*
+ * 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 "service/common/bluetooth/a2dp_codec_config.h"
+#include "stack/include/a2dp_vendor_ldac.h"
+
+bluetooth::A2dpCodecConfig* bta_av_get_a2dp_current_codec(void) {
+ return nullptr;
+}
+
+int A2DP_VendorGetTrackSampleRateLdac(const uint8_t* p_codec_info) { return 0; }
+int A2DP_VendorGetTrackBitsPerSampleLdac(const uint8_t* p_codec_info) {
+ return 0;
+}
+int A2DP_VendorGetChannelModeCodeLdac(const uint8_t* p_codec_info) { return 0; }