fix(core/emulator): start BLE driver in enabled state by default
What changed, and why it matters
This commit changes the Trezor firmware emulator's fake Bluetooth driver so it starts in an 'enabled' state by default. It only affects the Unix emulator build used for software testing, not real Trezor hardware. The change moves socket setup from the 'start' routine to the 'init' routine and adds a new flag tracking whether communication is running. There is no direct evidence this fixes a security vulnerability; it appears to be an emulator behavior or test-fix change.
Treat as a low-risk emulator behavior fix. If reviewing, verify the inverted guard in ble_get_mac() is intentional. No urgent action required for production devices because this code is not compiled into hardware firmware.
Security signals we found
Behavior change in emulator-only BLE driver initialization state
Guard condition inverted in ble_get_mac() (possible typo)
No changelog entry provided
No vendor security disclosure or CVE references present
Evidence from the diff
The patch modifies core/embed/io/ble/unix/ble.c, the emulator-only BLE driver. Previously, ble_init() registered system handles but left sockets unopened and the driver disabled; ble_start() zeroed the driver, opened UDP sockets, and set initialized=true. After the patch, ble_init() zeros the driver, opens the UDP sockets, and sets initialized=true and enabled=true. ble_start()/ble_stop() now only toggle a new comm_running flag, and is_enabled() requires comm_running as well. Several operations that previously required is_enabled() now only require initialized. The change also inverts the guard in ble_get_mac() from ‘if (!is_enabled)’ to ‘if (drv->initialized)’, which looks like a possible typo but is in emulator-only code.
Changed components
core/embed/io/ble/unix/ble.cTrezor firmware emulator (Unix BLE driver only)Inspect captured patch +32 / −24
diff --git a/core/embed/io/ble/unix/ble.c b/core/embed/io/ble/unix/ble.c
index 6564345d6..37dad1adc 100644
--- a/core/embed/io/ble/unix/ble.c
+++ b/core/embed/io/ble/unix/ble.c
@@ -16,6 +16,7 @@ static const uint16_t EVENT_PORT_OFFSET = 5;
typedef struct {
ble_mode_t mode_current;
bool initialized;
+ bool comm_running;
bool enabled;
bool pairing_requested;
uint8_t adv_name[BLE_ADV_NAME_LEN];
@@ -81,11 +82,12 @@ static void bonds_remove(ble_driver_t *drv, const bt_le_addr_t *addr) {
}
static bool is_enabled(const ble_driver_t *drv) {
- return (drv->initialized && drv->enabled);
+ return (drv->initialized && drv->enabled && drv->comm_running);
}
bool ble_init(void) {
ble_driver_t *drv = &g_ble_driver;
+ memset(drv, 0, sizeof(*drv));
sock_init(&drv->data_sock);
sock_init(&drv->event_sock);
if (!syshandle_register(SYSHANDLE_BLE, &ble_handle_vmt, drv)) {
@@ -95,6 +97,16 @@ bool ble_init(void) {
if (!syshandle_register(SYSHANDLE_BLE_IFACE_0, &ble_iface_handle_vmt, drv)) {
goto cleanup;
}
+
+ const char *ip = getenv("TREZOR_UDP_IP");
+ const char *port_base_str = getenv("TREZOR_UDP_PORT");
+ uint16_t port_base = port_base_str ? atoi(port_base_str) : 21324;
+
+ sock_start(&drv->data_sock, ip, port_base + DATA_PORT_OFFSET);
+ sock_start(&drv->event_sock, ip, port_base + EVENT_PORT_OFFSET);
+
+ drv->initialized = true;
+ drv->enabled = true;
return true;
cleanup:
@@ -104,22 +116,20 @@ cleanup:
}
void ble_deinit(void) {
+ ble_driver_t *drv = &g_ble_driver;
+
+ memset(drv, 0, sizeof(ble_driver_t));
+
+ sock_stop(&drv->data_sock);
+ sock_stop(&drv->event_sock);
+
syshandle_unregister(SYSHANDLE_BLE_IFACE_0);
syshandle_unregister(SYSHANDLE_BLE);
}
void ble_start(void) {
ble_driver_t *drv = &g_ble_driver;
- memset(drv, 0, sizeof(*drv));
-
- const char *ip = getenv("TREZOR_UDP_IP");
- const char *port_base_str = getenv("TREZOR_UDP_PORT");
- uint16_t port_base = port_base_str ? atoi(port_base_str) : 21324;
-
- sock_start(&drv->data_sock, ip, port_base + DATA_PORT_OFFSET);
- sock_start(&drv->event_sock, ip, port_base + EVENT_PORT_OFFSET);
-
- drv->initialized = true;
+ drv->comm_running = true;
}
void ble_stop(void) {
@@ -128,9 +138,7 @@ void ble_stop(void) {
return;
}
- sock_stop(&drv->data_sock);
- sock_stop(&drv->event_sock);
- drv->initialized = false;
+ drv->comm_running = false;
}
static bool send_to_emu(char cmdtype) {
@@ -156,7 +164,7 @@ static bool send_to_emu(char cmdtype) {
bool ble_switch_off(void) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return false;
}
drv->mode_current = BLE_MODE_OFF;
@@ -166,7 +174,7 @@ bool ble_switch_off(void) {
bool ble_switch_on(void) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return false;
}
if (drv->connected) {
@@ -189,7 +197,7 @@ bool ble_enter_pairing_mode(const uint8_t *name, size_t name_len) {
bool ble_disconnect(void) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return false;
}
drv->connected = false;
@@ -199,7 +207,7 @@ bool ble_disconnect(void) {
bool ble_erase_bonds(void) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return false;
}
printf("unix/ble: erase bonds\n");
@@ -223,7 +231,7 @@ bool ble_allow_pairing(const uint8_t *pairing_code) {
bool ble_reject_pairing(void) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return false;
}
drv->pairing_requested = false;
@@ -234,7 +242,7 @@ bool ble_reject_pairing(void) {
bool ble_keep_connection(void) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return false;
}
drv->mode_current = BLE_MODE_KEEP_CONNECTION;
@@ -243,7 +251,7 @@ bool ble_keep_connection(void) {
bool ble_get_event(ble_event_t *event) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return false;
}
@@ -311,7 +319,7 @@ void ble_get_state(ble_state_t *state) {
const ble_driver_t *drv = &g_ble_driver;
memset(state, 0, sizeof(ble_state_t));
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
return;
}
@@ -341,7 +349,7 @@ void ble_get_advertising_name(char *name, size_t max_len) {
return;
}
- if (!is_enabled(drv)) {
+ if (!drv->initialized) {
memset(name, 0, max_len);
return;
}
@@ -406,7 +414,7 @@ uint32_t ble_read(uint8_t *data, uint16_t max_len) {
bool ble_get_mac(bt_le_addr_t *addr) {
ble_driver_t *drv = &g_ble_driver;
- if (!is_enabled(drv)) {
+ if (drv->initialized) {
memset(addr, 0, sizeof(*addr));
return false;
}
Why this scored 14/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.