Skip to content

Commit 20a536f

Browse files
Fix 'use-after-free' or 'double-free' issues
1 parent 979a464 commit 20a536f

2 files changed

Lines changed: 27 additions & 9 deletions

File tree

src/features/generic_tx_parser/tx_ctx.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,23 +165,29 @@ static bool process_empty_tx(const s_tx_ctx *tx_ctx) {
165165
}
166166

167167
bool process_empty_txs_before(void) {
168-
for (list_node_t *tmp = ((list_node_t *) g_tx_ctx_current)->prev;
169-
(tmp != NULL) && (((s_tx_ctx *) tmp)->calldata == NULL);
170-
tmp = tmp->prev) {
168+
list_node_t *tmp = ((list_node_t *) g_tx_ctx_current)->prev;
169+
while ((tmp != NULL) && (((s_tx_ctx *) tmp)->calldata == NULL)) {
170+
// process_empty_tx calls list_remove + delete_tx_ctx, which frees tmp.
171+
// Ensure reading tmp->prev before the call to avoid use-after-free.
172+
list_node_t *prev = tmp->prev;
171173
if (!process_empty_tx((s_tx_ctx *) tmp)) {
172174
return false;
173175
}
176+
tmp = prev;
174177
}
175178
return true;
176179
}
177180

178181
bool process_empty_txs_after(void) {
179-
for (flist_node_t *tmp = ((flist_node_t *) g_tx_ctx_current)->next;
180-
(tmp != NULL) && (((s_tx_ctx *) tmp)->calldata == NULL);
181-
tmp = tmp->next) {
182+
flist_node_t *tmp = ((flist_node_t *) g_tx_ctx_current)->next;
183+
while ((tmp != NULL) && (((s_tx_ctx *) tmp)->calldata == NULL)) {
184+
// process_empty_tx calls list_remove + delete_tx_ctx, which frees tmp.
185+
// Ensure reading tmp->next before the call to avoid use-after-free.
186+
flist_node_t *next = tmp->next;
182187
if (!process_empty_tx((s_tx_ctx *) tmp)) {
183188
return false;
184189
}
190+
tmp = next;
185191
}
186192
return true;
187193
}
@@ -291,6 +297,15 @@ bool tx_ctx_init(s_calldata *calldata,
291297
return false;
292298
}
293299
list_push_back((list_node_t **) &g_tx_ctx_list, (list_node_t *) node);
300+
301+
// Ownership of the calldata has been transferred to the node.
302+
// Clear g_parked_calldata now so callers cannot double-free it if we return
303+
// false below (e.g. when field_table_init fails after the node is in the list
304+
// and will be freed by tx_ctx_cleanup via delete_tx_ctx).
305+
if (g_parked_calldata == calldata) {
306+
g_parked_calldata = NULL;
307+
}
308+
294309
if ((appState == APP_STATE_SIGNING_TX) && (node == g_tx_ctx_list)) {
295310
return field_table_init();
296311
}

src/features/provide_network_info/network_info.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,14 @@ void network_info_cleanup(network_info_t *network) {
417417
// Remove from list
418418
flist_remove((flist_node_t **) &g_dynamic_network_list, (flist_node_t *) network, NULL);
419419

420-
// Free the network info structure
421-
APP_MEM_FREE_AND_NULL((void **) &network);
420+
// Save address before freeing to check if it's the last added network
421+
bool was_last = (g_last_added_network == network);
422+
423+
// Free the network info structure (local parameter — no need to null it)
424+
APP_MEM_FREE((void *) network);
422425

423426
// Reset last added network pointer if it was this network
424-
if (g_last_added_network == network) {
427+
if (was_last) {
425428
g_last_added_network = NULL;
426429
// Also cleanup temporary buffers associated with this network
427430
clear_icon();

0 commit comments

Comments
 (0)