Skip to content

Commit f1859ac

Browse files
Merge pull request #506 from LedgerHQ/fbe/align_swap_behavior
Return to Exchange when failing to sign in swap mode
2 parents 93712e2 + 60d1d97 commit f1859ac

File tree

4 files changed

+28
-0
lines changed

4 files changed

+28
-0
lines changed

src/handle_swap_sign_transaction.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ void handle_swap_sign_transaction(chain_config_t* config) {
8080
chainConfig = config;
8181
reset_app_context();
8282
G_called_from_swap = true;
83+
G_swap_response_ready = false;
8384
io_seproxyhal_init();
8485

8586
if (N_storage.initialized != 0x01) {

src/main.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ cx_sha3_t global_sha3;
5353
uint8_t appState;
5454
uint16_t apdu_response_code;
5555
bool G_called_from_swap;
56+
bool G_swap_response_ready;
5657
pluginType_t pluginType;
5758
#ifdef HAVE_STARKWARE
5859
bool quantumSet;
@@ -78,6 +79,7 @@ void reset_app_context() {
7879
// PRINTF("!!RESET_APP_CONTEXT\n");
7980
appState = APP_STATE_IDLE;
8081
G_called_from_swap = false;
82+
G_swap_response_ready = false;
8183
pluginType = OLD_INTERNAL;
8284
#ifdef HAVE_STARKWARE
8385
quantumSet = false;
@@ -456,6 +458,7 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
456458
THROW(EXCEPTION_IO_RESET);
457459
}
458460
CATCH_OTHER(e) {
461+
bool quit_now = G_called_from_swap && G_swap_response_ready;
459462
switch (e & 0xF000) {
460463
case 0x6000:
461464
// Wipe the transaction context and report the exception
@@ -476,6 +479,18 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
476479
G_io_apdu_buffer[*tx] = sw >> 8;
477480
G_io_apdu_buffer[*tx + 1] = sw;
478481
*tx += 2;
482+
483+
// If we are in swap mode and have validated a TX, we send it and immediately quit
484+
if (quit_now) {
485+
if (io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, *tx) == 0) {
486+
// In case of success, the apdu is sent immediatly and eth exits
487+
// Reaching this code means we encountered an error
488+
finalize_exchange_sign_transaction(false);
489+
} else {
490+
PRINTF("Unrecoverable\n");
491+
os_sched_exit(-1);
492+
}
493+
}
479494
}
480495
FINALLY {
481496
}

src/shared_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ extern cx_sha3_t global_sha3;
215215
extern const internalStorage_t N_storage_real;
216216

217217
extern bool G_called_from_swap;
218+
extern bool G_swap_response_ready;
218219

219220
typedef enum {
220221
EXTERNAL, // External plugin, set by setExternalPlugin.

src_features/signTx/logic_signTx.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,15 @@ void finalizeParsing(bool direct) {
433433
}
434434
}
435435

436+
if (G_called_from_swap) {
437+
if (G_swap_response_ready) {
438+
// Unreachable given current return to exchange mechanism. Safeguard against regression
439+
PRINTF("FATAL: safety against double sign triggered\n");
440+
os_sched_exit(-1);
441+
}
442+
G_swap_response_ready = true;
443+
}
444+
436445
// User has just validated a swap but ETH received apdus about a non standard plugin / contract
437446
if (G_called_from_swap && !use_standard_UI) {
438447
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, G_called_from_swap\n");
@@ -504,6 +513,8 @@ void finalizeParsing(bool direct) {
504513
// Ensure the values are the same that the ones that have been previously validated
505514
if (strcmp(strings.common.maxFee, displayBuffer) != 0) {
506515
PRINTF("ERR_SILENT_MODE_CHECK_FAILED, fees check failed\n");
516+
PRINTF("Expected %s\n", strings.common.maxFee);
517+
PRINTF("Received %s\n", displayBuffer);
507518
THROW(ERR_SILENT_MODE_CHECK_FAILED);
508519
}
509520
} else {

0 commit comments

Comments
 (0)