ble: be consistent in initializing structs
What changed, and why it matters
This commit changes how three internal Bluetooth-related data structures are initialized in the Blockstream Jade hardware wallet firmware. Previously, two structures were declared without initialization and later zeroed with memset(), while one was declared without initialization and never zeroed. Now all three are initialized to zero at the point of declaration, and the redundant memset() calls are removed. The change is defensive and reduces the risk that future edits could accidentally use uninitialized memory. There is no direct evidence in the commit that this fixes an exploitable security vulnerability.
Treat as a low-risk hardening improvement. No urgent action required unless an independent security assessment identifies a specific exploit path involving the previously uninitialized ble_gap_upd_params fields. Reviewers may want to confirm that all NimBLE structs used in this file follow the same zero-initialization pattern.
Security signals we found
Uninitialized stack variable in BLE connection parameter handling (ble_gap_upd_params) is now zero-initialized
Defensive initialization pattern applied consistently across BLE structs
Removal of memset() calls in favor of declaration-time initialization
Evidence from the diff
In main/ble/ble.c, the patch converts struct ble_gap_adv_params adv_params, struct ble_hs_adv_fields fields, and struct ble_gap_upd_params params from uninitialized declarations to zero-initialized declarations ({0}). It removes the corresponding memset() calls for the first two. The third struct (params in ble_gap_event) was previously declared uninitialized and only three fields were explicitly set; the remaining fields could have contained stack garbage. The patch ensures all fields are zeroed before use, which is a code-hardening measure consistent with the commit title ‘be consistent in initializing structs’.
Changed components
main/ble/ble.cBluetooth Low Energy (BLE) advertising setupBLE connection event handlingInspect captured patch +3 / −6
diff --git a/main/ble/ble.c b/main/ble/ble.c
index e947032..227ebe0 100644
--- a/main/ble/ble.c
+++ b/main/ble/ble.c
@@ -247,16 +247,14 @@ static void ble_start_advertising(void)
// Reset the write size assuming preferred MTU
set_ble_max_write_size_for_mtu(CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU);
- struct ble_gap_adv_params adv_params;
- struct ble_hs_adv_fields fields;
+ struct ble_gap_adv_params adv_params = { 0 };
+ struct ble_hs_adv_fields fields = { 0 };
const char* name;
int rc;
// All we really need in the advertising packet is the device name ('Jade abcdef' - 11 bytes)
// and the service id (128bit - 16bytes) - with 2 bytes of overhead (type, length) per field,
// this takes up the entire advertising packet (31 bytes max.)
- memset(&fields, 0, sizeof fields);
-
name = ble_svc_gap_device_name();
fields.name = (uint8_t*)name;
fields.name_len = strlen(name);
@@ -278,7 +276,6 @@ static void ble_start_advertising(void)
rc = ble_gap_adv_set_fields(&fields);
JADE_ASSERT_MSG(rc == 0, "ble_gap_adv_set_fields() failed with error %d", rc);
- memset(&adv_params, 0, sizeof adv_params);
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
@@ -592,7 +589,7 @@ static int ble_gap_event(struct ble_gap_event* event, void* arg)
// Note: these values are in specific units/increments
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
JADE_ASSERT(rc == 0);
- struct ble_gap_upd_params params;
+ struct ble_gap_upd_params params = { 0 };
params.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN;
params.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX;
params.latency = desc.conn_latency;
Why this scored 28/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.