diff --git a/drivers/bluetooth/hci/h4.c b/drivers/bluetooth/hci/h4.c index 5fdacbf0171..b8c77282b49 100644 --- a/drivers/bluetooth/hci/h4.c +++ b/drivers/bluetooth/hci/h4.c @@ -281,6 +281,8 @@ static inline void read_payload(void) int read; if (!rx.buf) { + size_t buf_tailroom; + rx.buf = get_rx(K_NO_WAIT); if (!rx.buf) { if (rx.discardable) { @@ -297,8 +299,10 @@ static inline void read_payload(void) BT_DBG("Allocated rx.buf %p", rx.buf); - if (rx.remaining > net_buf_tailroom(rx.buf)) { - BT_ERR("Not enough space in buffer"); + buf_tailroom = net_buf_tailroom(rx.buf); + if (buf_tailroom < rx.remaining) { + BT_ERR("Not enough space in buffer %u/%zu", + rx.remaining, buf_tailroom); rx.discard = rx.remaining; reset_rx(); return; diff --git a/drivers/bluetooth/hci/h5.c b/drivers/bluetooth/hci/h5.c index 57e25d3fdce..ac8ebcced30 100644 --- a/drivers/bluetooth/hci/h5.c +++ b/drivers/bluetooth/hci/h5.c @@ -415,6 +415,7 @@ static void bt_uart_isr(const struct device *unused, void *user_data) uint8_t byte; int ret; static uint8_t hdr[4]; + size_t buf_tailroom; ARG_UNUSED(unused); ARG_UNUSED(user_data); @@ -535,6 +536,14 @@ static void bt_uart_isr(const struct device *unused, void *user_data) } } + buf_tailroom = net_buf_tailroom(h5.rx_buf); + if (buf_tailroom < sizeof(byte)) { + BT_ERR("Not enough space in buffer %zu/%zu", + sizeof(byte), buf_tailroom); + h5_reset_rx(); + break; + } + net_buf_add_mem(h5.rx_buf, &byte, sizeof(byte)); remaining--; if (!remaining) { diff --git a/drivers/bluetooth/hci/hci_esp32.c b/drivers/bluetooth/hci/hci_esp32.c index 76272917f0a..43171a8100f 100644 --- a/drivers/bluetooth/hci/hci_esp32.c +++ b/drivers/bluetooth/hci/hci_esp32.c @@ -57,6 +57,7 @@ static struct net_buf *bt_esp_evt_recv(uint8_t *data, size_t remaining) bool discardable = false; struct bt_hci_evt_hdr hdr; struct net_buf *buf; + size_t buf_tailroom; if (remaining < sizeof(hdr)) { BT_ERR("Not enough data for event header"); @@ -86,6 +87,15 @@ static struct net_buf *bt_esp_evt_recv(uint8_t *data, size_t remaining) } net_buf_add_mem(buf, &hdr, sizeof(hdr)); + + buf_tailroom = net_buf_tailroom(buf); + if (buf_tailroom < remaining) { + BT_ERR("Not enough space in buffer %zu/%zu", + remaining, buf_tailroom); + net_buf_unref(buf); + continue; + } + net_buf_add_mem(buf, data, remaining); return buf; @@ -95,6 +105,7 @@ static struct net_buf *bt_esp_acl_recv(uint8_t *data, size_t remaining) { struct bt_hci_acl_hdr hdr; struct net_buf *buf; + size_t buf_tailroom; if (remaining < sizeof(hdr)) { BT_ERR("Not enough data for ACL header"); @@ -119,6 +130,14 @@ static struct net_buf *bt_esp_acl_recv(uint8_t *data, size_t remaining) return NULL; } + buf_tailroom = net_buf_tailroom(buf); + if (buf_tailroom < remaining) { + BT_ERR("Not enough space in buffer %zu/%zu", + remaining, buf_tailroom); + net_buf_unref(buf); + return NULL; + } + BT_DBG("len %u", remaining); net_buf_add_mem(buf, data, remaining); @@ -129,6 +148,7 @@ static struct net_buf *bt_esp_iso_recv(uint8_t *data, size_t remaining) { struct bt_hci_iso_hdr hdr; struct net_buf *buf; + size_t buf_tailroom; if (remaining < sizeof(hdr)) { BT_ERR("Not enough data for ISO header"); @@ -153,6 +173,14 @@ static struct net_buf *bt_esp_iso_recv(uint8_t *data, size_t remaining) return NULL; } + buf_tailroom = net_buf_tailroom(buf); + if (buf_tailroom < remaining) { + BT_ERR("Not enough space in buffer %zu/%zu", + remaining, buf_tailroom); + net_buf_unref(buf); + return NULL; + } + BT_DBG("len %zu", remaining); net_buf_add_mem(buf, data, remaining); diff --git a/drivers/bluetooth/hci/ipm_stm32wb.c b/drivers/bluetooth/hci/ipm_stm32wb.c index cee7cb8d444..fb0c6a1f494 100644 --- a/drivers/bluetooth/hci/ipm_stm32wb.c +++ b/drivers/bluetooth/hci/ipm_stm32wb.c @@ -160,6 +160,8 @@ static void bt_ipm_rx_thread(void) struct bt_hci_acl_hdr acl_hdr; TL_AclDataSerial_t *acl; struct bt_hci_evt_le_meta_event *mev; + size_t buf_tailroom; + size_t buf_add_len; hcievt = k_fifo_get(&ipm_rx_events_fifo, K_FOREVER); @@ -195,8 +197,18 @@ static void bt_ipm_rx_thread(void) } tryfix_event(&hcievt->evtserial.evt); + + buf_tailroom = net_buf_tailroom(buf); + buf_add_len = hcievt->evtserial.evt.plen + 2; + if (buf_tailroom < buf_add_len) { + BT_ERR("Not enough space in buffer %zu/%zu", + buf_add_len, buf_tailroom); + net_buf_unref(buf); + goto end_loop; + } + net_buf_add_mem(buf, &hcievt->evtserial.evt, - hcievt->evtserial.evt.plen + 2); + buf_add_len); break; case HCI_ACL: acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial); @@ -206,8 +218,18 @@ static void bt_ipm_rx_thread(void) BT_DBG("ACL: handle %x, len %x", acl_hdr.handle, acl_hdr.len); net_buf_add_mem(buf, &acl_hdr, sizeof(acl_hdr)); + + buf_tailroom = net_buf_tailroom(buf); + buf_add_len = acl_hdr.len; + if (buf_tailroom < buf_add_len) { + BT_ERR("Not enough space in buffer %zu/%zu", + buf_add_len, buf_tailroom); + net_buf_unref(buf); + goto end_loop; + } + net_buf_add_mem(buf, (uint8_t *)&acl->acl_data, - acl_hdr.len); + buf_add_len); break; default: BT_ERR("Unknown BT buf type %d", diff --git a/drivers/bluetooth/hci/rpmsg.c b/drivers/bluetooth/hci/rpmsg.c index 06f1f1a5411..1f702089ab8 100644 --- a/drivers/bluetooth/hci/rpmsg.c +++ b/drivers/bluetooth/hci/rpmsg.c @@ -57,6 +57,7 @@ static struct net_buf *bt_rpmsg_evt_recv(uint8_t *data, size_t remaining) bool discardable; struct bt_hci_evt_hdr hdr; struct net_buf *buf; + size_t buf_tailroom; if (remaining < sizeof(hdr)) { BT_ERR("Not enough data for event header"); @@ -86,6 +87,15 @@ static struct net_buf *bt_rpmsg_evt_recv(uint8_t *data, size_t remaining) } net_buf_add_mem(buf, &hdr, sizeof(hdr)); + + buf_tailroom = net_buf_tailroom(buf); + if (buf_tailroom < remaining) { + BT_ERR("Not enough space in buffer %zu/%zu", + remaining, buf_tailroom); + net_buf_unref(buf); + return NULL; + } + net_buf_add_mem(buf, data, remaining); return buf; @@ -95,6 +105,7 @@ static struct net_buf *bt_rpmsg_acl_recv(uint8_t *data, size_t remaining) { struct bt_hci_acl_hdr hdr; struct net_buf *buf; + size_t buf_tailroom; if (remaining < sizeof(hdr)) { BT_ERR("Not enough data for ACL header"); @@ -119,6 +130,14 @@ static struct net_buf *bt_rpmsg_acl_recv(uint8_t *data, size_t remaining) return NULL; } + buf_tailroom = net_buf_tailroom(buf); + if (buf_tailroom < remaining) { + BT_ERR("Not enough space in buffer %zu/%zu", + remaining, buf_tailroom); + net_buf_unref(buf); + return NULL; + } + BT_DBG("len %u", remaining); net_buf_add_mem(buf, data, remaining); @@ -129,6 +148,7 @@ static struct net_buf *bt_rpmsg_iso_recv(uint8_t *data, size_t remaining) { struct bt_hci_iso_hdr hdr; struct net_buf *buf; + size_t buf_tailroom; if (remaining < sizeof(hdr)) { BT_ERR("Not enough data for ISO header"); @@ -153,6 +173,14 @@ static struct net_buf *bt_rpmsg_iso_recv(uint8_t *data, size_t remaining) return NULL; } + buf_tailroom = net_buf_tailroom(buf); + if (buf_tailroom < remaining) { + BT_ERR("Not enough space in buffer %zu/%zu", + remaining, buf_tailroom); + net_buf_unref(buf); + return NULL; + } + BT_DBG("len %zu", remaining); net_buf_add_mem(buf, data, remaining); diff --git a/drivers/bluetooth/hci/userchan.c b/drivers/bluetooth/hci/userchan.c index 275ab5d29e2..1dc5a9f5dc5 100644 --- a/drivers/bluetooth/hci/userchan.c +++ b/drivers/bluetooth/hci/userchan.c @@ -103,6 +103,8 @@ static void rx_thread(void *p1, void *p2, void *p3) while (1) { static uint8_t frame[512]; struct net_buf *buf; + size_t buf_tailroom; + size_t buf_add_len; ssize_t len; if (!uc_ready()) { @@ -131,7 +133,16 @@ static void rx_thread(void *p1, void *p2, void *p3) continue; } - net_buf_add_mem(buf, &frame[1], len - 1); + buf_tailroom = net_buf_tailroom(buf); + buf_add_len = len - 1; + if (buf_tailroom < buf_add_len) { + BT_ERR("Not enough space in buffer %zu/%zu", + buf_add_len, buf_tailroom); + net_buf_unref(buf); + continue; + } + + net_buf_add_mem(buf, &frame[1], buf_add_len); BT_DBG("Calling bt_recv(%p)", buf);