Bluetooth: drivers: Add length checks before net_buf_add_mem
Add length checks before calls to net_buf_add_mem for dynamically sized data. This should give a better error response than hitting the __ASSERT in net_buf_simple_add. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
0ef5dac70e
commit
b988c803f6
6 changed files with 107 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue