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;
|
int read;
|
||||||
|
|
||||||
if (!rx.buf) {
|
if (!rx.buf) {
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
rx.buf = get_rx(K_NO_WAIT);
|
rx.buf = get_rx(K_NO_WAIT);
|
||||||
if (!rx.buf) {
|
if (!rx.buf) {
|
||||||
if (rx.discardable) {
|
if (rx.discardable) {
|
||||||
|
@ -297,8 +299,10 @@ static inline void read_payload(void)
|
||||||
|
|
||||||
BT_DBG("Allocated rx.buf %p", rx.buf);
|
BT_DBG("Allocated rx.buf %p", rx.buf);
|
||||||
|
|
||||||
if (rx.remaining > net_buf_tailroom(rx.buf)) {
|
buf_tailroom = net_buf_tailroom(rx.buf);
|
||||||
BT_ERR("Not enough space in buffer");
|
if (buf_tailroom < rx.remaining) {
|
||||||
|
BT_ERR("Not enough space in buffer %u/%zu",
|
||||||
|
rx.remaining, buf_tailroom);
|
||||||
rx.discard = rx.remaining;
|
rx.discard = rx.remaining;
|
||||||
reset_rx();
|
reset_rx();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -415,6 +415,7 @@ static void bt_uart_isr(const struct device *unused, void *user_data)
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
int ret;
|
int ret;
|
||||||
static uint8_t hdr[4];
|
static uint8_t hdr[4];
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
ARG_UNUSED(unused);
|
ARG_UNUSED(unused);
|
||||||
ARG_UNUSED(user_data);
|
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));
|
net_buf_add_mem(h5.rx_buf, &byte, sizeof(byte));
|
||||||
remaining--;
|
remaining--;
|
||||||
if (!remaining) {
|
if (!remaining) {
|
||||||
|
|
|
@ -57,6 +57,7 @@ static struct net_buf *bt_esp_evt_recv(uint8_t *data, size_t remaining)
|
||||||
bool discardable = false;
|
bool discardable = false;
|
||||||
struct bt_hci_evt_hdr hdr;
|
struct bt_hci_evt_hdr hdr;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
if (remaining < sizeof(hdr)) {
|
if (remaining < sizeof(hdr)) {
|
||||||
BT_ERR("Not enough data for event header");
|
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));
|
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);
|
net_buf_add_mem(buf, data, remaining);
|
||||||
|
|
||||||
return buf;
|
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 bt_hci_acl_hdr hdr;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
if (remaining < sizeof(hdr)) {
|
if (remaining < sizeof(hdr)) {
|
||||||
BT_ERR("Not enough data for ACL header");
|
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;
|
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);
|
BT_DBG("len %u", remaining);
|
||||||
net_buf_add_mem(buf, data, 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 bt_hci_iso_hdr hdr;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
if (remaining < sizeof(hdr)) {
|
if (remaining < sizeof(hdr)) {
|
||||||
BT_ERR("Not enough data for ISO header");
|
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;
|
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);
|
BT_DBG("len %zu", remaining);
|
||||||
net_buf_add_mem(buf, data, 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;
|
struct bt_hci_acl_hdr acl_hdr;
|
||||||
TL_AclDataSerial_t *acl;
|
TL_AclDataSerial_t *acl;
|
||||||
struct bt_hci_evt_le_meta_event *mev;
|
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);
|
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);
|
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,
|
net_buf_add_mem(buf, &hcievt->evtserial.evt,
|
||||||
hcievt->evtserial.evt.plen + 2);
|
buf_add_len);
|
||||||
break;
|
break;
|
||||||
case HCI_ACL:
|
case HCI_ACL:
|
||||||
acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial);
|
acl = &(((TL_AclDataPacket_t *)hcievt)->AclDataSerial);
|
||||||
|
@ -206,8 +218,18 @@ static void bt_ipm_rx_thread(void)
|
||||||
BT_DBG("ACL: handle %x, len %x",
|
BT_DBG("ACL: handle %x, len %x",
|
||||||
acl_hdr.handle, acl_hdr.len);
|
acl_hdr.handle, acl_hdr.len);
|
||||||
net_buf_add_mem(buf, &acl_hdr, sizeof(acl_hdr));
|
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,
|
net_buf_add_mem(buf, (uint8_t *)&acl->acl_data,
|
||||||
acl_hdr.len);
|
buf_add_len);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BT_ERR("Unknown BT buf type %d",
|
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;
|
bool discardable;
|
||||||
struct bt_hci_evt_hdr hdr;
|
struct bt_hci_evt_hdr hdr;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
if (remaining < sizeof(hdr)) {
|
if (remaining < sizeof(hdr)) {
|
||||||
BT_ERR("Not enough data for event header");
|
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));
|
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);
|
net_buf_add_mem(buf, data, remaining);
|
||||||
|
|
||||||
return buf;
|
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 bt_hci_acl_hdr hdr;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
if (remaining < sizeof(hdr)) {
|
if (remaining < sizeof(hdr)) {
|
||||||
BT_ERR("Not enough data for ACL header");
|
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;
|
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);
|
BT_DBG("len %u", remaining);
|
||||||
net_buf_add_mem(buf, data, 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 bt_hci_iso_hdr hdr;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
size_t buf_tailroom;
|
||||||
|
|
||||||
if (remaining < sizeof(hdr)) {
|
if (remaining < sizeof(hdr)) {
|
||||||
BT_ERR("Not enough data for ISO header");
|
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;
|
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);
|
BT_DBG("len %zu", remaining);
|
||||||
net_buf_add_mem(buf, data, remaining);
|
net_buf_add_mem(buf, data, remaining);
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,8 @@ static void rx_thread(void *p1, void *p2, void *p3)
|
||||||
while (1) {
|
while (1) {
|
||||||
static uint8_t frame[512];
|
static uint8_t frame[512];
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
size_t buf_tailroom;
|
||||||
|
size_t buf_add_len;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
if (!uc_ready()) {
|
if (!uc_ready()) {
|
||||||
|
@ -131,7 +133,16 @@ static void rx_thread(void *p1, void *p2, void *p3)
|
||||||
continue;
|
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);
|
BT_DBG("Calling bt_recv(%p)", buf);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue