From 6896075b62ce07ec09e6acbd546f2847205aa9b0 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 21 Apr 2022 16:11:48 +0200 Subject: [PATCH] Bluetooth: Mesh: add check for rx buffer overflow in pb adv There is potential buffer overflow in pb adv. If Transaction Continuation PDU comes before Transaction Start PDU the last segment number is set to 0xff. The current implementation has a strictly limited buffer size. It is possible to receive malformed frame with wrong segment number. All segments with number 2 and above will be stored in the memory behind Rx buffer. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/pb_adv.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/pb_adv.c b/subsys/bluetooth/mesh/pb_adv.c index 5bebd4d3c24..015df3e96e8 100644 --- a/subsys/bluetooth/mesh/pb_adv.c +++ b/subsys/bluetooth/mesh/pb_adv.c @@ -29,6 +29,7 @@ #define START_PAYLOAD_MAX 20 #define CONT_PAYLOAD_MAX 23 +#define RX_BUFFER_MAX 65 #define START_LAST_SEG(gpc) (gpc >> 2) #define CONT_SEG_INDEX(gpc) (gpc >> 2) @@ -38,7 +39,8 @@ #define LINK_ACK 0x01 #define LINK_CLOSE 0x02 -#define XACT_SEG_DATA(_seg) (&link.rx.buf->data[20 + ((_seg - 1) * 23)]) +#define XACT_SEG_OFFSET(_seg) (20 + ((_seg - 1) * 23)) +#define XACT_SEG_DATA(_seg) (&link.rx.buf->data[XACT_SEG_OFFSET(_seg)]) #define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg))) #define XACT_ID_MAX 0x7f @@ -116,7 +118,7 @@ struct prov_rx { uint8_t gpc; }; -NET_BUF_SIMPLE_DEFINE_STATIC(rx_buf, 65); +NET_BUF_SIMPLE_DEFINE_STATIC(rx_buf, RX_BUFFER_MAX); static struct pb_adv link = { .rx = { .buf = &rx_buf } }; @@ -383,6 +385,11 @@ static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf) return; } + if (XACT_SEG_OFFSET(seg) + buf->len > RX_BUFFER_MAX) { + BT_WARN("Rx buffer overflow. Malformed generic prov frame?"); + return; + } + memcpy(XACT_SEG_DATA(seg), buf->data, buf->len); XACT_SEG_RECV(seg);