This is an automated email from the ASF dual-hosted git repository. sjanc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 694d8b36d22463fcb504a05693eac025b5777b0f Author: Szymon Janc <[email protected]> AuthorDate: Wed Oct 7 18:09:26 2026 +0200 nimble/ll/test: Add tests for HCI ISO data packet boundary flags Verify that HCI ISO data packets with unexpected Packet Boundary flags or truncated header are handled without leaking buffers. Assisted-by: Claude:claude-opus-5-5 --- nimble/controller/test/src/ble_ll_iso.c | 173 ++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) diff --git a/nimble/controller/test/src/ble_ll_iso.c b/nimble/controller/test/src/ble_ll_iso.c index 93e511d3c..66b546fe4 100644 --- a/nimble/controller/test/src/ble_ll_iso.c +++ b/nimble/controller/test/src/ble_ll_iso.c @@ -35,6 +35,15 @@ #define TSPX_max_tx_nse 3 #define TSPX_max_tx_payload 32 +#define TEST_BUF_SIZE \ + (sizeof(struct os_mbuf) + sizeof(struct os_mbuf_pkthdr) + \ + sizeof(struct ble_mbuf_hdr) + 64) +#define TEST_BUF_COUNT (10) + +static struct os_mbuf_pool g_test_mbuf_pool; +static struct os_mempool g_test_mempool; +static os_membuf_t g_test_mbuf_buffer[OS_MEMPOOL_SIZE(TEST_BUF_COUNT, TEST_BUF_SIZE)]; + /* LL.TS.p24 4.11.2 Common Parameters */ struct test_ll_common_params { uint8_t TxNumBIS; @@ -212,11 +221,175 @@ TEST_CASE_SELF(test_ll_ist_brd_bv_01_c) test_ll_iso_teardown(&fixture); } +static void +test_ll_iso_data_in_init(void) +{ + int rc; + + rc = os_mempool_init(&g_test_mempool, TEST_BUF_COUNT, TEST_BUF_SIZE, + &g_test_mbuf_buffer[0], "test_iso_pool"); + TEST_ASSERT_FATAL(rc == 0); + + rc = os_mbuf_pool_init(&g_test_mbuf_pool, &g_test_mempool, TEST_BUF_SIZE, + TEST_BUF_COUNT); + TEST_ASSERT_FATAL(rc == 0); +} + +static int +test_ll_iso_data_in(uint16_t conn_handle, uint8_t pb_flag, uint16_t data_len) +{ + struct ble_hci_iso_data hci_iso_data; + struct ble_hci_iso hci_iso; + struct os_mbuf *om; + uint8_t data = 0; + uint16_t len; + int rc; + + om = os_mbuf_get_pkthdr(&g_test_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(om != NULL); + + len = data_len; + if ((pb_flag == BLE_HCI_ISO_PB_FIRST) || (pb_flag == BLE_HCI_ISO_PB_COMPLETE)) { + len += sizeof(hci_iso_data); + } + + hci_iso.handle = htole16(BLE_HCI_ISO_HANDLE(conn_handle, pb_flag, 0)); + hci_iso.length = htole16(len); + rc = os_mbuf_append(om, &hci_iso, sizeof(hci_iso)); + TEST_ASSERT_FATAL(rc == 0); + + if ((pb_flag == BLE_HCI_ISO_PB_FIRST) || (pb_flag == BLE_HCI_ISO_PB_COMPLETE)) { + hci_iso_data.packet_seq_num = 0; + hci_iso_data.sdu_len = htole16(data_len); + rc = os_mbuf_append(om, &hci_iso_data, sizeof(hci_iso_data)); + TEST_ASSERT_FATAL(rc == 0); + } + + while (data_len--) { + rc = os_mbuf_append(om, &data, 1); + TEST_ASSERT_FATAL(rc == 0); + } + + return ble_ll_iso_data_in(om); +} + +static void +test_ll_iso_data_in_teardown(struct test_ll_iso_fixture *fixture) +{ + test_ll_iso_teardown(fixture); + + /* Memory leak test */ + TEST_ASSERT(g_test_mempool.mp_num_free == TEST_BUF_COUNT, + "mp_num_free is %d", g_test_mempool.mp_num_free); +} + +TEST_CASE_SELF(test_ll_iso_data_in_continuation_without_first) +{ + struct test_ll_iso_fixture fixture; + int rc; + + test_ll_iso_setup(&fixture, &test_ll_common_params_bn_1); + + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_CONTINUATION, 4); + TEST_ASSERT(rc == BLE_ERR_INV_HCI_CMD_PARMS); + + test_ll_iso_data_in_teardown(&fixture); +} + +TEST_CASE_SELF(test_ll_iso_data_in_last_without_first) +{ + struct test_ll_iso_fixture fixture; + int rc; + + test_ll_iso_setup(&fixture, &test_ll_common_params_bn_1); + + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_LAST, 4); + TEST_ASSERT(rc == BLE_ERR_INV_HCI_CMD_PARMS); + + test_ll_iso_data_in_teardown(&fixture); +} + +TEST_CASE_SELF(test_ll_iso_data_in_first_while_pending) +{ + struct test_ll_iso_fixture fixture; + int rc; + + test_ll_iso_setup(&fixture, &test_ll_common_params_bn_1); + + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_FIRST, 4); + TEST_ASSERT(rc == 0); + + /* Pending fragment shall be dropped */ + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_FIRST, 4); + TEST_ASSERT(rc == 0); + + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_LAST, 4); + TEST_ASSERT(rc == 0); + + /* Pending fragment shall be dropped */ + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_FIRST, 4); + TEST_ASSERT(rc == 0); + + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_COMPLETE, 4); + TEST_ASSERT(rc == 0); + + test_ll_iso_data_in_teardown(&fixture); +} + +TEST_CASE_SELF(test_ll_iso_data_in_pending_on_free) +{ + struct test_ll_iso_fixture fixture; + int rc; + + test_ll_iso_setup(&fixture, &test_ll_common_params_bn_1); + + rc = test_ll_iso_data_in(fixture.conn.handle, BLE_HCI_ISO_PB_FIRST, 4); + TEST_ASSERT(rc == 0); + + /* Pending fragment shall be freed with ISO connection */ + test_ll_iso_data_in_teardown(&fixture); +} + +TEST_CASE_SELF(test_ll_iso_data_in_short_header) +{ + struct test_ll_iso_fixture fixture; + struct os_mbuf *om; + uint8_t hdr[4]; + int rc; + + test_ll_iso_setup(&fixture, &test_ll_common_params_bn_1); + + om = os_mbuf_get_pkthdr(&g_test_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(om != NULL); + + put_le16(&hdr[0], + BLE_HCI_ISO_HANDLE(fixture.conn.handle, BLE_HCI_ISO_PB_COMPLETE, 0)); + put_le16(&hdr[2], sizeof(struct ble_hci_iso_data)); + rc = os_mbuf_append(om, hdr, sizeof(hdr)); + TEST_ASSERT_FATAL(rc == 0); + + /* Only handle is included in packet */ + os_mbuf_adj(om, -2); + + rc = ble_ll_iso_data_in(om); + TEST_ASSERT(rc == BLE_ERR_INV_HCI_CMD_PARMS); + + test_ll_iso_data_in_teardown(&fixture); +} + TEST_SUITE(ble_ll_iso_test_suite) { ble_ll_iso_init(); + test_ll_iso_data_in_init(); + test_ll_ist_brd_bv_01_c(); + test_ll_iso_data_in_continuation_without_first(); + test_ll_iso_data_in_last_without_first(); + test_ll_iso_data_in_first_while_pending(); + test_ll_iso_data_in_pending_on_free(); + test_ll_iso_data_in_short_header(); + ble_ll_iso_reset(); }
