From 7e39db9bce035414dc3173fefaadfab27f21d2c2 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Tue, 19 Mar 2024 14:35:24 +0100 Subject: [PATCH] Bluetooth: Mesh: analyze multicast model rx status Commit adds analyzing of returned status of element rx. If at least one element receives multicast message then access layer will return suceess status. If option CONFIG_BT_MESH_ACCESS_LAYER_MSG is enabled then access layer will return success always. Function bt_mesh_access_recv has been introduced to cover case when real model statuses should be returned over oppcode aggregator model despite access returns success. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/Kconfig | 8 ++++++++ subsys/bluetooth/mesh/access.c | 24 ++++++++++++++++++++++-- subsys/bluetooth/mesh/access.h | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index b7590b8790e..88fccf0961c 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -697,6 +697,14 @@ config BT_MESH_ACCESS_LAYER_MSG Bluetooth access layer messages without the need to instantiate Bluetooth Mesh models. + Please note that Bluetooth Mesh stack stores authentication sequence from + any message that passed over network cache if this option is enabled. + It happens despite the device does not have necessary application keys or + there are unknown model operation codes. It causes the situation when device + will update the replay protection cache for messages those cannot be handled + in the stack. For example, spamming broadcast messages those stack cannot handle + might wear out persistent memory. + config BT_MESH_MODEL_VND_MSG_CID_FORCE bool "Force vendor model to use the corresponding CID field message" default y diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 51471097c9e..0ad4e7164ad 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1545,17 +1545,20 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) if (index >= dev_comp->elem_count) { LOG_ERR("Invalid address 0x%02x", ctx->recv_dst); - err = ACCESS_STATUS_INVALID_ADDRESS; + return ACCESS_STATUS_INVALID_ADDRESS; } else { const struct bt_mesh_elem *elem = &dev_comp->elem[index]; err = element_model_recv(ctx, buf, elem, opcode); } } else { + err = ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD; for (index = 0; index < dev_comp->elem_count; index++) { const struct bt_mesh_elem *elem = &dev_comp->elem[index]; + int err_elem; - (void)element_model_recv(ctx, buf, elem, opcode); + err_elem = element_model_recv(ctx, buf, elem, opcode); + err = err_elem == ACCESS_STATUS_SUCCESS ? err_elem : err; } } @@ -1566,6 +1569,23 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) return err; } +int bt_mesh_access_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) +{ + int err; + + err = bt_mesh_model_recv(ctx, buf); + + if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) { + /* Mesh assumes that the application has processed the message. + * Access layer returns success to trigger RPL update and prevent + * replay attack over application. + */ + err = 0; + } + + return err; +} + int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg, const struct bt_mesh_send_cb *cb, void *cb_data) diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 210fceee319..ff1728b371c 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -59,6 +59,7 @@ const struct bt_mesh_comp *bt_mesh_comp_get(void); const struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx); +int bt_mesh_access_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); int bt_mesh_comp_register(const struct bt_mesh_comp *comp);