mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
fix(ble/bluedroid): Add length check in prepare write response
(cherry picked from commit b03ff3cf21)
Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
This commit is contained in:
@@ -66,7 +66,7 @@ static const UINT16 disc_type_to_uuid[GATT_DISC_MAX] = {
|
|||||||
0 /* no type filtering for DISC_CHAR_DSCPT */
|
0 /* no type filtering for DISC_CHAR_DSCPT */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use for GATTC discover infomation print
|
// Use for GATTC discover information print
|
||||||
#define GATT_DISC_INFO(fmt, args...) {if (gatt_cb.auto_disc == FALSE) BT_PRINT_I("BT_GATT", fmt, ## args);}
|
#define GATT_DISC_INFO(fmt, args...) {if (gatt_cb.auto_disc == FALSE) BT_PRINT_I("BT_GATT", fmt, ## args);}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -604,7 +604,7 @@ void gatt_process_prep_write_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op
|
|||||||
|
|
||||||
GATT_TRACE_DEBUG("value resp op_code = %s len = %d", gatt_dbg_op_name(op_code), len);
|
GATT_TRACE_DEBUG("value resp op_code = %s len = %d", gatt_dbg_op_name(op_code), len);
|
||||||
|
|
||||||
if (len < GATT_PREP_WRITE_RSP_MIN_LEN) {
|
if ((len < GATT_PREP_WRITE_RSP_MIN_LEN) || ((len - 4) > GATT_MAX_ATTR_LEN)) {
|
||||||
GATT_TRACE_ERROR("illegal prepare write response length, discard");
|
GATT_TRACE_ERROR("illegal prepare write response length, discard");
|
||||||
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
|
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
|
||||||
return;
|
return;
|
||||||
@@ -701,7 +701,7 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code,
|
|||||||
}
|
}
|
||||||
p_tcb->ind_count = 0;
|
p_tcb->ind_count = 0;
|
||||||
|
|
||||||
/* should notify all registered client with the handle value notificaion/indication
|
/* should notify all registered client with the handle value notification/indication
|
||||||
Note: need to do the indication count and start timer first then do callback
|
Note: need to do the indication count and start timer first then do callback
|
||||||
*/
|
*/
|
||||||
for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
|
for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
|
||||||
@@ -800,7 +800,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
|||||||
handle_len = 4;
|
handle_len = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_len -= handle_len; /* substract the handle pairs bytes */
|
value_len -= handle_len; /* subtract the handle pairs bytes */
|
||||||
len -= 1;
|
len -= 1;
|
||||||
|
|
||||||
while (len >= (handle_len + value_len)) {
|
while (len >= (handle_len + value_len)) {
|
||||||
@@ -887,7 +887,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
|||||||
gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p);
|
gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else { /* discover characterisitic */
|
} else { /* discover characteristic */
|
||||||
STREAM_TO_UINT8 (record_value.dclr_value.char_prop, p);
|
STREAM_TO_UINT8 (record_value.dclr_value.char_prop, p);
|
||||||
STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
|
STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
|
||||||
if (!GATT_HANDLE_IS_VALID(record_value.dclr_value.val_handle)) {
|
if (!GATT_HANDLE_IS_VALID(record_value.dclr_value.val_handle)) {
|
||||||
@@ -979,7 +979,7 @@ void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
|
|||||||
|
|
||||||
if (len == (p_tcb->payload_size - 1) && /* full packet for read or read blob rsp */
|
if (len == (p_tcb->payload_size - 1) && /* full packet for read or read blob rsp */
|
||||||
len + offset < GATT_MAX_ATTR_LEN) {
|
len + offset < GATT_MAX_ATTR_LEN) {
|
||||||
GATT_TRACE_DEBUG("full pkt issue read blob for remianing bytes old offset=%d len=%d new offset=%d",
|
GATT_TRACE_DEBUG("full pkt issue read blob for remaining bytes old offset=%d len=%d new offset=%d",
|
||||||
offset, len, p_clcb->counter);
|
offset, len, p_clcb->counter);
|
||||||
gatt_act_read(p_clcb, p_clcb->counter);
|
gatt_act_read(p_clcb, p_clcb->counter);
|
||||||
} else { /* end of request, send callback */
|
} else { /* end of request, send callback */
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ enum {
|
|||||||
};
|
};
|
||||||
typedef UINT8 tSMP_BR_STATE;
|
typedef UINT8 tSMP_BR_STATE;
|
||||||
|
|
||||||
/* random and encrption activity state */
|
/* random and encryption activity state */
|
||||||
enum {
|
enum {
|
||||||
SMP_GEN_COMPARE = 1,
|
SMP_GEN_COMPARE = 1,
|
||||||
SMP_GEN_CONFIRM,
|
SMP_GEN_CONFIRM,
|
||||||
@@ -363,6 +363,9 @@ extern tSMP_CB *smp_cb_ptr;
|
|||||||
/* Functions provided by att_main.c */
|
/* Functions provided by att_main.c */
|
||||||
extern void smp_init (void);
|
extern void smp_init (void);
|
||||||
|
|
||||||
|
/* SMP command sizes per spec - defined in smp_utils.c */
|
||||||
|
extern const UINT8 smp_cmd_size_per_spec[];
|
||||||
|
|
||||||
/* smp main */
|
/* smp main */
|
||||||
extern void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data);
|
extern void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data);
|
||||||
|
|
||||||
|
|||||||
@@ -156,15 +156,31 @@ static void smp_connect_callback (UINT16 channel, BD_ADDR bd_addr, BOOLEAN conne
|
|||||||
static void smp_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
|
static void smp_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
|
||||||
{
|
{
|
||||||
tSMP_CB *p_cb = &smp_cb;
|
tSMP_CB *p_cb = &smp_cb;
|
||||||
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
UINT8 *p;
|
||||||
UINT8 cmd ;
|
UINT8 cmd;
|
||||||
SMP_TRACE_EVENT ("\nSMDBG l2c %s\n", __FUNCTION__);
|
SMP_TRACE_EVENT ("\nSMDBG l2c %s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
/* Validate packet length before accessing data to prevent out-of-bounds read */
|
||||||
|
if (p_buf->len < 1) {
|
||||||
|
SMP_TRACE_WARNING ("Ignore empty SMP packet (len=%d)\n", p_buf->len);
|
||||||
|
osi_free (p_buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||||
STREAM_TO_UINT8(cmd, p);
|
STREAM_TO_UINT8(cmd, p);
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) {
|
if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) {
|
||||||
SMP_TRACE_WARNING( "Ignore received command with RESERVED code 0x%02x\n", cmd);
|
SMP_TRACE_WARNING ("Ignore received command with RESERVED code 0x%02x\n", cmd);
|
||||||
|
osi_free (p_buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate command length to prevent out-of-bounds read in handler functions */
|
||||||
|
if (p_buf->len != smp_cmd_size_per_spec[cmd]) {
|
||||||
|
SMP_TRACE_WARNING ("Ignore SMP cmd 0x%02x with invalid length %d (expected %d)\n",
|
||||||
|
cmd, p_buf->len, smp_cmd_size_per_spec[cmd]);
|
||||||
osi_free (p_buf);
|
osi_free (p_buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
#define SMP_PAIR_KEYPR_NOTIF_SIZE (1 /* opcode */ + 1 /*Notif Type*/)
|
#define SMP_PAIR_KEYPR_NOTIF_SIZE (1 /* opcode */ + 1 /*Notif Type*/)
|
||||||
|
|
||||||
/* SMP command sizes per spec */
|
/* SMP command sizes per spec */
|
||||||
static const UINT8 smp_cmd_size_per_spec[] = {
|
const UINT8 smp_cmd_size_per_spec[] = {
|
||||||
0,
|
0,
|
||||||
SMP_PAIRING_REQ_SIZE, /* 0x01: pairing request */
|
SMP_PAIRING_REQ_SIZE, /* 0x01: pairing request */
|
||||||
SMP_PAIRING_REQ_SIZE, /* 0x02: pairing response */
|
SMP_PAIRING_REQ_SIZE, /* 0x02: pairing response */
|
||||||
|
|||||||
Reference in New Issue
Block a user