Skip to content

Commit be46692

Browse files
authored
fix(legacy): fix the safe exec transaction signing issue due to memory reuse (#177)
1 parent ae331ad commit be46692

File tree

2 files changed

+52
-26
lines changed

2 files changed

+52
-26
lines changed

legacy/buttons.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,10 @@ bool waitButtonResponse(uint8_t btn, uint32_t time_out) {
203203
// stub implementations
204204
void enableLongPress(bool on) { (void)on; }
205205
bool getLongPressStatus(void) { return false; }
206-
bool isLongPress(uint8_t key) { (void)key; return false; }
206+
bool isLongPress(uint8_t key) {
207+
(void)key;
208+
return false;
209+
}
207210
#endif
208211

209212
void buttonUpdate(void) {

legacy/firmware/ethereum_onekey.c

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,7 @@ static bool ethereum_signing_handle_safe_tx(const struct signing_params *params,
13631363
} else {
13641364
// safe exec transaction
13651365
display_info_init(&display_info, 14);
1366-
const uint8_t *data = params->data_initial_chunk_bytes + 16;
1366+
uint8_t *data = (uint8_t *)params->data_initial_chunk_bytes + 16;
13671367
display_info_add_item_name(&display_info, "to", 0);
13681368
uint8_t to[20];
13691369
memcpy(to, data, 20);
@@ -1375,7 +1375,7 @@ static bool ethereum_signing_handle_safe_tx(const struct signing_params *params,
13751375
display_info_set_value(&display_info, value_str);
13761376
free(value_str);
13771377
// display_info_add_item_name(&display_info, "operation", 0);
1378-
uint8_t operation = data[105];
1378+
uint8_t operation = data[115];
13791379
char operation_str[16];
13801380
if (operation == 0) {
13811381
strcpy(operation_str, "0(Call)");
@@ -1396,24 +1396,35 @@ static bool ethereum_signing_handle_safe_tx(const struct signing_params *params,
13961396
for (uint8_t i = 0; i < 32; i++) {
13971397
data_len = (data_len << 8) | data[308 + i];
13981398
}
1399-
data_left = params->data_length - params->data_initial_chunk_size;
1399+
uint8_t *remaining_data = NULL;
14001400
if (data_left > 0) {
1401+
data = (uint8_t *)malloc(668);
1402+
if (data == NULL) {
1403+
fsm_sendFailure(FailureType_Failure_DataError,
1404+
"Failed to allocate memory");
1405+
return false;
1406+
}
1407+
memcpy(data, (uint8_t *)params->data_initial_chunk_bytes + 356, 668);
14011408
data_left_bytes = (uint8_t *)malloc(data_left);
14021409
if (data_left_bytes == NULL) {
1410+
free(data);
14031411
fsm_sendFailure(FailureType_Failure_DataError,
14041412
"Failed to allocate memory");
14051413
return false;
14061414
}
14071415
uint32_t data_left_pos = 0;
1408-
while (data_left > 0) {
1416+
uint32_t data_left_dummy = data_left;
1417+
while (data_left_dummy > 0) {
14091418
msg_tx_request.has_data_length = true;
1410-
msg_tx_request.data_length = data_left <= 1024 ? data_left : 1024;
1419+
msg_tx_request.data_length =
1420+
data_left_dummy <= 1024 ? data_left_dummy : 1024;
14111421
void *response_ptr =
14121422
call(MessageType_MessageType_EthereumTxRequestOneKey,
14131423
&msg_tx_request, MessageType_MessageType_EthereumTxAckOneKey);
14141424
if (response_ptr == NULL) {
14151425
free(data_left_bytes);
14161426
data_left_bytes = NULL;
1427+
free(data);
14171428
display_info_cleanup(&display_info);
14181429
fsm_sendFailure(FailureType_Failure_DataError, "Invalid call data");
14191430
return false;
@@ -1422,11 +1433,28 @@ static bool ethereum_signing_handle_safe_tx(const struct signing_params *params,
14221433
memcpy(data_left_bytes + data_left_pos, resp.data_chunk.bytes,
14231434
resp.data_chunk.size);
14241435
data_left_pos += resp.data_chunk.size;
1425-
data_left -= resp.data_chunk.size;
1436+
data_left_dummy -= resp.data_chunk.size;
14261437
}
14271438
}
1428-
if (data_len > 0 && data_left == 0) {
1429-
const uint8_t *nest_data = data + 340;
1439+
if (data_len > 0) {
1440+
const uint8_t *nest_data = NULL;
1441+
if (data_left_bytes != NULL) {
1442+
remaining_data = (uint8_t *)malloc(params->data_length - 356);
1443+
if (remaining_data == NULL) {
1444+
free(data);
1445+
free(data_left_bytes);
1446+
data_left_bytes = NULL;
1447+
fsm_sendFailure(FailureType_Failure_DataError,
1448+
"Failed to allocate memory");
1449+
return false;
1450+
}
1451+
memcpy(remaining_data, data, 668);
1452+
memcpy(remaining_data + 668, data_left_bytes, data_left);
1453+
nest_data = (const uint8_t *)remaining_data;
1454+
free(data);
1455+
} else {
1456+
nest_data = data + 340;
1457+
}
14301458
display_info_add_item_name(&display_info, "data", 0);
14311459
if (data_len == 68 && memcmp(nest_data,
14321460
"\xa9\x05\x9c\xbb\x00\x00\x00\x00\x00\x00"
@@ -1514,6 +1542,8 @@ static bool ethereum_signing_handle_safe_tx(const struct signing_params *params,
15141542
free(gas_price_str);
15151543
free(gas_token_str);
15161544
free(refund_receiver_str);
1545+
free(remaining_data);
1546+
remaining_data = NULL;
15171547
data_left_bytes = NULL;
15181548
}
15191549
display_info_cleanup(&display_info);
@@ -1538,16 +1568,7 @@ static bool ethereum_signing_handle_safe_tx(const struct signing_params *params,
15381568
display_info_set_value(&display_info, refund_receiver_str);
15391569
free(refund_receiver_str);
15401570
uint8_t *signature_data = NULL;
1541-
uint8_t *remaining_data = NULL;
15421571
if (data_left_bytes != NULL) {
1543-
remaining_data = (uint8_t *)malloc(params->data_length - 340);
1544-
if (remaining_data == NULL) {
1545-
fsm_sendFailure(FailureType_Failure_DataError,
1546-
"Failed to allocate memory");
1547-
return false;
1548-
}
1549-
memcpy(remaining_data, data + 340, 1024 - 340);
1550-
memcpy(remaining_data + 1024 - 340, data_left_bytes, data_left);
15511572
signature_data = remaining_data + (signature_pos - 340);
15521573
} else {
15531574
signature_data = (uint8_t *)(data + signature_pos);
@@ -1579,14 +1600,6 @@ static bool ethereum_signing_safe_tx(
15791600
uint32_t max_priority_fee_per_gas_len) {
15801601
SafeTxContext safe_tx_context = {0};
15811602
bool is_delegate_call = false;
1582-
if (!ethereum_signing_handle_safe_tx(params, &safe_tx_context,
1583-
&is_delegate_call)) {
1584-
if (safe_tx_context.payload.approve_hash != NULL) {
1585-
free(safe_tx_context.payload.approve_hash);
1586-
safe_tx_context.payload.approve_hash = NULL;
1587-
}
1588-
return false;
1589-
}
15901603
char max_fee_per_gas_str[32] = {0};
15911604
char priority_fee_per_gas_str[32] = {0};
15921605
char max_fee_str[32] = {0};
@@ -1605,6 +1618,14 @@ static bool ethereum_signing_safe_tx(
16051618
char *nonce_ptr = decode_typed_data(nonce, nonce_len, "uint");
16061619
memcpy(nonce_str, nonce_ptr, strlen(nonce_ptr));
16071620
free(nonce_ptr);
1621+
if (!ethereum_signing_handle_safe_tx(params, &safe_tx_context,
1622+
&is_delegate_call)) {
1623+
if (safe_tx_context.payload.approve_hash != NULL) {
1624+
free(safe_tx_context.payload.approve_hash);
1625+
safe_tx_context.payload.approve_hash = NULL;
1626+
}
1627+
return false;
1628+
}
16081629
bool result = false;
16091630
if (safe_tx_context.type == SafeTxContextType_APPROVE_HASH) {
16101631
result = layoutEthereumConfirmApproveHash(
@@ -1905,6 +1926,7 @@ void ethereum_signing_init_onekey(const EthereumSignTxOneKey *msg,
19051926
hash_data(data_left_bytes, data_left);
19061927
free(data_left_bytes);
19071928
data_left_bytes = NULL;
1929+
data_left = 0;
19081930
}
19091931
send_signature();
19101932
}
@@ -2082,6 +2104,7 @@ void ethereum_signing_init_eip1559_onekey(
20822104
hash_data(data_left_bytes, data_left);
20832105
free(data_left_bytes);
20842106
data_left_bytes = NULL;
2107+
data_left = 0;
20852108
}
20862109
send_signature();
20872110
}

0 commit comments

Comments
 (0)