This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 164f1c23c18a290908df76ed83fe848bfe4a4903
Author: Mariusz Skamra <[email protected]>
AuthorDate: Thu Aug 14 12:42:57 2025 +0200

    nimble/ll: Restrict allowed LL Control PDUs received
    
    This restricts allowed Control PDUs that can be received in specific
    encryption state.
---
 nimble/controller/include/controller/ble_ll_ctrl.h |  3 +-
 nimble/controller/src/ble_ll_conn.c                |  2 +-
 nimble/controller/src/ble_ll_ctrl.c                | 46 +++++++++++++++++++++-
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h 
b/nimble/controller/include/controller/ble_ll_ctrl.h
index 402755988..918cc977b 100644
--- a/nimble/controller/include/controller/ble_ll_ctrl.h
+++ b/nimble/controller/include/controller/ble_ll_ctrl.h
@@ -306,7 +306,8 @@ uint8_t ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm 
*connsm,
 int ble_ll_ctrl_reject_ind_send(struct ble_ll_conn_sm *connsm,
                                 uint8_t rej_opcode, uint8_t err);
 int ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm);
-int ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu);
+int ble_ll_ctrl_enc_allowed_pdu_rx(struct ble_ll_conn_sm *connsm,
+                                   struct os_mbuf *rxpdu);
 int ble_ll_ctrl_enc_allowed_pdu_tx(struct os_mbuf_pkthdr *pkthdr);
 int ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu);
 int ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm);
diff --git a/nimble/controller/src/ble_ll_conn.c 
b/nimble/controller/src/ble_ll_conn.c
index bd3f2f64d..e74f8b615 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -3533,7 +3533,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct 
ble_mbuf_hdr *hdr)
          CONN_IS_CENTRAL(connsm)) ||
         (connsm->enc_data.enc_state >= CONN_ENC_S_ENC_RSP_TO_BE_SENT &&
          CONN_IS_PERIPHERAL(connsm))) {
-        if (!ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) {
+        if (!ble_ll_ctrl_enc_allowed_pdu_rx(connsm, rxpdu)) {
             ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
             goto conn_rx_data_pdu_end;
         }
diff --git a/nimble/controller/src/ble_ll_ctrl.c 
b/nimble/controller/src/ble_ll_ctrl.c
index bfb9de7e3..6a13c28ed 100644
--- a/nimble/controller/src/ble_ll_ctrl.c
+++ b/nimble/controller/src/ble_ll_ctrl.c
@@ -1451,11 +1451,13 @@ ble_ll_ctrl_enc_allowed_pdu(uint8_t llid, uint8_t len, 
uint8_t opcode)
 }
 
 int
-ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu)
+ble_ll_ctrl_enc_allowed_pdu_rx(struct ble_ll_conn_sm *connsm, struct os_mbuf 
*rxpdu)
 {
     uint8_t llid;
     uint8_t len;
     uint8_t opcode;
+    uint8_t state;
+    int allowed;
 
     llid = rxpdu->om_data[0] & BLE_LL_DATA_HDR_LLID_MASK;
     len = rxpdu->om_data[1];
@@ -1465,7 +1467,47 @@ ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu)
         opcode = 0;
     }
 
-    return ble_ll_ctrl_enc_allowed_pdu(llid, len, opcode);
+    allowed = 0;
+    state = connsm->enc_data.enc_state;
+
+    switch (llid) {
+    case BLE_LL_LLID_CTRL:
+        switch (opcode) {
+        case BLE_LL_CTRL_REJECT_IND:
+        case BLE_LL_CTRL_REJECT_IND_EXT:
+            allowed = state == CONN_ENC_S_ENC_RSP_WAIT ||
+                      state == CONN_ENC_S_START_ENC_REQ_WAIT;
+            break;
+        case BLE_LL_CTRL_START_ENC_RSP:
+            allowed = state == CONN_ENC_S_START_ENC_RSP_WAIT;
+            break;
+        case BLE_LL_CTRL_START_ENC_REQ:
+            allowed = state == CONN_ENC_S_START_ENC_REQ_WAIT;
+            break;
+        case BLE_LL_CTRL_ENC_REQ:
+            allowed = state == CONN_ENC_S_ENCRYPTED || state == 
CONN_ENC_S_PAUSED;
+            break;
+        case BLE_LL_CTRL_ENC_RSP:
+            allowed = state == CONN_ENC_S_ENC_RSP_WAIT;
+            break;
+        case BLE_LL_CTRL_PAUSE_ENC_REQ:
+            allowed = state == CONN_ENC_S_ENCRYPTED;
+            break;
+        case BLE_LL_CTRL_PAUSE_ENC_RSP:
+            allowed = state == CONN_ENC_S_PAUSE_ENC_RSP_WAIT;
+            break;
+        case BLE_LL_CTRL_TERMINATE_IND:
+            allowed = 1;
+            break;
+        }
+        break;
+    case BLE_LL_LLID_DATA_FRAG:
+        /* Empty PDUs are allowed */
+        allowed = len == 0;
+        break;
+    }
+
+    return allowed;
 }
 
 int

Reply via email to