Skip to content

Commit 9a9918c

Browse files
Merge pull request #950 from LedgerHQ/fix/apa/security_review
1.21.0 security review fixes
2 parents ea79f77 + 48f7714 commit 9a9918c

7 files changed

Lines changed: 122 additions & 82 deletions

File tree

src/features/generic_tx_parser/gtp_param_calldata.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "utils.h"
88
#include "read.h"
99
#include "tx_ctx.h"
10+
#include "mem.h"
1011

1112
enum {
1213
TAG_VERSION = 0x00,
@@ -146,8 +147,11 @@ static bool process_nested_calldata(const s_param_calldata *param,
146147
calldata_length = calldata->length - CALLDATA_SELECTOR_SIZE;
147148
}
148149

149-
if (((new_calldata = calldata_init(calldata_length, selector_buf)) == NULL) ||
150-
!calldata_append(new_calldata, calldata_buf, calldata_length)) {
150+
if ((new_calldata = calldata_init(calldata_length, selector_buf)) == NULL) {
151+
return false;
152+
}
153+
if (!calldata_append(new_calldata, calldata_buf, calldata_length)) {
154+
app_mem_free(new_calldata);
151155
return false;
152156
}
153157
}

src/features/provide_trusted_name/trusted_name.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ bool verify_trusted_name_struct(const s_trusted_name_ctx *context) {
659659
return false;
660660
}
661661

662-
size_t name_length = strlen(context->trusted_name.name);
662+
size_t name_length = strnlen(context->trusted_name.name, sizeof(context->trusted_name.name));
663663
if ((context->trusted_name.struct_version == 1) ||
664664
((context->trusted_name.name_type == TN_TYPE_ACCOUNT) &&
665665
(context->trusted_name.name_source == TN_SOURCE_ENS))) {

src/features/signTx/ethUstream.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,9 @@ static bool processChainID(txContext_t *context) {
175175
if (context->currentFieldPos < context->currentFieldLength) {
176176
uint32_t copySize =
177177
MIN(context->commandLength, context->currentFieldLength - context->currentFieldPos);
178-
if (copyTxData(context, context->content->chainID.value, copySize) == false) {
178+
if (copyTxData(context,
179+
context->content->chainID.value + context->currentFieldPos,
180+
copySize) == false) {
179181
return false;
180182
}
181183
}
@@ -195,7 +197,9 @@ static bool processNonce(txContext_t *context) {
195197
if (context->currentFieldPos < context->currentFieldLength) {
196198
uint32_t copySize =
197199
MIN(context->commandLength, context->currentFieldLength - context->currentFieldPos);
198-
if (copyTxData(context, context->content->nonce.value, copySize) == false) {
200+
if (copyTxData(context,
201+
context->content->nonce.value + context->currentFieldPos,
202+
copySize) == false) {
199203
return false;
200204
}
201205
}

src/plugins/eip7002/eip7002_plugin.c

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,29 @@ static void eip7002_plugin_init_contract(ethPluginInitContract_t *param) {
3737
eip7002_context_t *context = (eip7002_context_t *) param->pluginContext;
3838

3939
explicit_bzero(context, sizeof(*context));
40-
memcpy(&context->withdrawal_request[context->received], param->selector, SELECTOR_SIZE);
41-
context->received += SELECTOR_SIZE;
42-
param->result = ETH_PLUGIN_RESULT_OK;
40+
if ((context->received + CALLDATA_SELECTOR_SIZE) > sizeof(context->withdrawal_request)) {
41+
param->result = ETH_PLUGIN_RESULT_ERROR;
42+
} else {
43+
memcpy(&context->withdrawal_request[context->received],
44+
param->selector,
45+
CALLDATA_SELECTOR_SIZE);
46+
context->received += CALLDATA_SELECTOR_SIZE;
47+
param->result = ETH_PLUGIN_RESULT_OK;
48+
}
4349
}
4450

4551
static void eip7002_plugin_provider_parameter(ethPluginProvideParameter_t *param) {
4652
eip7002_context_t *context = (eip7002_context_t *) param->pluginContext;
4753

4854
if ((context->received + param->parameter_size) > sizeof(context->withdrawal_request)) {
4955
param->result = ETH_PLUGIN_RESULT_ERROR;
56+
} else {
57+
memcpy(&context->withdrawal_request[context->received],
58+
param->parameter,
59+
param->parameter_size);
60+
context->received += param->parameter_size;
61+
param->result = ETH_PLUGIN_RESULT_OK;
5062
}
51-
memcpy(&context->withdrawal_request[context->received],
52-
param->parameter,
53-
param->parameter_size);
54-
context->received += param->parameter_size;
55-
param->result = ETH_PLUGIN_RESULT_OK;
5663
}
5764

5865
static void eip7002_plugin_finalize(ethPluginFinalize_t *param) {
@@ -84,6 +91,9 @@ static void eip7002_plugin_query_contract_ui(ethQueryContractUI_t *param) {
8491

8592
switch (param->screenIndex) {
8693
case 0:
94+
if (param->msgLength < 2) {
95+
return;
96+
}
8797
strlcpy(param->title, "Validator", param->titleLength);
8898
memcpy(param->msg, "0x", 2);
8999
format_hex(context->validator_pubkey,
@@ -110,23 +120,25 @@ static void eip7002_plugin_query_contract_ui(ethQueryContractUI_t *param) {
110120
}
111121

112122
void eip7002_plugin_call(eth_plugin_msg_t msg, void *param) {
113-
switch (msg) {
114-
case ETH_PLUGIN_INIT_CONTRACT:
115-
eip7002_plugin_init_contract(param);
116-
break;
117-
case ETH_PLUGIN_PROVIDE_PARAMETER:
118-
eip7002_plugin_provider_parameter(param);
119-
break;
120-
case ETH_PLUGIN_FINALIZE:
121-
eip7002_plugin_finalize(param);
122-
break;
123-
case ETH_PLUGIN_QUERY_CONTRACT_ID:
124-
eip7002_plugin_query_contract_id(param);
125-
break;
126-
case ETH_PLUGIN_QUERY_CONTRACT_UI:
127-
eip7002_plugin_query_contract_ui(param);
128-
break;
129-
default:
130-
PRINTF("Unhandled message 0x%x\n", msg);
123+
if (param != NULL) {
124+
switch (msg) {
125+
case ETH_PLUGIN_INIT_CONTRACT:
126+
eip7002_plugin_init_contract(param);
127+
break;
128+
case ETH_PLUGIN_PROVIDE_PARAMETER:
129+
eip7002_plugin_provider_parameter(param);
130+
break;
131+
case ETH_PLUGIN_FINALIZE:
132+
eip7002_plugin_finalize(param);
133+
break;
134+
case ETH_PLUGIN_QUERY_CONTRACT_ID:
135+
eip7002_plugin_query_contract_id(param);
136+
break;
137+
case ETH_PLUGIN_QUERY_CONTRACT_UI:
138+
eip7002_plugin_query_contract_ui(param);
139+
break;
140+
default:
141+
PRINTF("Unhandled message 0x%x\n", msg);
142+
}
131143
}
132144
}

src/plugins/eip7251/eip7251_plugin.c

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,29 @@ static void eip7251_plugin_init_contract(ethPluginInitContract_t *param) {
3939
eip7251_context_t *context = (eip7251_context_t *) param->pluginContext;
4040

4141
explicit_bzero(context, sizeof(*context));
42-
memcpy(&context->consolidation_request[context->received], param->selector, SELECTOR_SIZE);
43-
context->received += SELECTOR_SIZE;
44-
param->result = ETH_PLUGIN_RESULT_OK;
42+
if ((context->received + CALLDATA_SELECTOR_SIZE) > sizeof(context->consolidation_request)) {
43+
param->result = ETH_PLUGIN_RESULT_ERROR;
44+
} else {
45+
memcpy(&context->consolidation_request[context->received],
46+
param->selector,
47+
CALLDATA_SELECTOR_SIZE);
48+
context->received += CALLDATA_SELECTOR_SIZE;
49+
param->result = ETH_PLUGIN_RESULT_OK;
50+
}
4551
}
4652

4753
static void eip7251_plugin_provider_parameter(ethPluginProvideParameter_t *param) {
4854
eip7251_context_t *context = (eip7251_context_t *) param->pluginContext;
4955

5056
if ((context->received + param->parameter_size) > sizeof(context->consolidation_request)) {
5157
param->result = ETH_PLUGIN_RESULT_ERROR;
58+
} else {
59+
memcpy(&context->consolidation_request[context->received],
60+
param->parameter,
61+
param->parameter_size);
62+
context->received += param->parameter_size;
63+
param->result = ETH_PLUGIN_RESULT_OK;
5264
}
53-
memcpy(&context->consolidation_request[context->received],
54-
param->parameter,
55-
param->parameter_size);
56-
context->received += param->parameter_size;
57-
param->result = ETH_PLUGIN_RESULT_OK;
5865
}
5966

6067
static void eip7251_plugin_finalize(ethPluginFinalize_t *param) {
@@ -80,50 +87,54 @@ static void eip7251_plugin_query_contract_id(ethQueryContractID_t *param) {
8087
static void eip7251_plugin_query_contract_ui(ethQueryContractUI_t *param) {
8188
eip7251_context_t *context = (eip7251_context_t *) param->pluginContext;
8289

83-
memcpy(param->msg, "0x", 2);
84-
switch (param->screenIndex) {
85-
case 0:
86-
if (target_equals_source(context)) {
87-
strlcpy(param->title, "Validator", param->titleLength);
88-
} else {
89-
strlcpy(param->title, "From validator", param->titleLength);
90-
}
91-
format_hex(context->source_pubkey,
92-
sizeof(context->source_pubkey),
93-
&param->msg[2],
94-
param->msgLength - 2);
95-
break;
96-
case 1:
97-
strlcpy(param->title, "To validator", param->titleLength);
98-
format_hex(context->target_pubkey,
99-
sizeof(context->target_pubkey),
100-
&param->msg[2],
101-
param->msgLength - 2);
102-
break;
103-
default:
104-
break;
90+
if (param->msgLength >= 2) {
91+
memcpy(param->msg, "0x", 2);
92+
switch (param->screenIndex) {
93+
case 0:
94+
if (target_equals_source(context)) {
95+
strlcpy(param->title, "Validator", param->titleLength);
96+
} else {
97+
strlcpy(param->title, "From validator", param->titleLength);
98+
}
99+
format_hex(context->source_pubkey,
100+
sizeof(context->source_pubkey),
101+
&param->msg[2],
102+
param->msgLength - 2);
103+
break;
104+
case 1:
105+
strlcpy(param->title, "To validator", param->titleLength);
106+
format_hex(context->target_pubkey,
107+
sizeof(context->target_pubkey),
108+
&param->msg[2],
109+
param->msgLength - 2);
110+
break;
111+
default:
112+
break;
113+
}
114+
param->result = ETH_PLUGIN_RESULT_OK;
105115
}
106-
param->result = ETH_PLUGIN_RESULT_OK;
107116
}
108117

109118
void eip7251_plugin_call(eth_plugin_msg_t msg, void *param) {
110-
switch (msg) {
111-
case ETH_PLUGIN_INIT_CONTRACT:
112-
eip7251_plugin_init_contract(param);
113-
break;
114-
case ETH_PLUGIN_PROVIDE_PARAMETER:
115-
eip7251_plugin_provider_parameter(param);
116-
break;
117-
case ETH_PLUGIN_FINALIZE:
118-
eip7251_plugin_finalize(param);
119-
break;
120-
case ETH_PLUGIN_QUERY_CONTRACT_ID:
121-
eip7251_plugin_query_contract_id(param);
122-
break;
123-
case ETH_PLUGIN_QUERY_CONTRACT_UI:
124-
eip7251_plugin_query_contract_ui(param);
125-
break;
126-
default:
127-
PRINTF("Unhandled message 0x%x\n", msg);
119+
if (param != NULL) {
120+
switch (msg) {
121+
case ETH_PLUGIN_INIT_CONTRACT:
122+
eip7251_plugin_init_contract(param);
123+
break;
124+
case ETH_PLUGIN_PROVIDE_PARAMETER:
125+
eip7251_plugin_provider_parameter(param);
126+
break;
127+
case ETH_PLUGIN_FINALIZE:
128+
eip7251_plugin_finalize(param);
129+
break;
130+
case ETH_PLUGIN_QUERY_CONTRACT_ID:
131+
eip7251_plugin_query_contract_id(param);
132+
break;
133+
case ETH_PLUGIN_QUERY_CONTRACT_UI:
134+
eip7251_plugin_query_contract_ui(param);
135+
break;
136+
default:
137+
PRINTF("Unhandled message 0x%x\n", msg);
138+
}
128139
}
129140
}

src/plugins/erc20/erc20_plugin.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,13 @@ void erc20_plugin_call(eth_plugin_msg_t message, void *parameters) {
103103
memmove(context->extra_data + extra_data_offset,
104104
msg->parameter,
105105
CALLDATA_CHUNK_SIZE);
106-
context->extra_data_len += msg->parameter_size;
107-
msg->result = ETH_PLUGIN_RESULT_OK;
106+
if (msg->parameter_size <= CALLDATA_CHUNK_SIZE) {
107+
context->extra_data_len += msg->parameter_size;
108+
msg->result = ETH_PLUGIN_RESULT_OK;
109+
} else {
110+
PRINTF("Error: wrong parameter size!\n");
111+
msg->result = ETH_PLUGIN_RESULT_ERROR;
112+
}
108113
} else {
109114
PRINTF("Extra data too long to buffer\n");
110115
context->extra_data_len = 0;

src/plugins/eth2/eth2_plugin.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ typedef struct eth2_deposit_parameters_t {
3939
} eth2_deposit_parameters_t;
4040

4141
void eth2_plugin_call(eth_plugin_msg_t message, void *parameters) {
42+
if (parameters == NULL) {
43+
return;
44+
}
4245
switch (message) {
4346
case ETH_PLUGIN_INIT_CONTRACT: {
4447
ethPluginInitContract_t *msg = (ethPluginInitContract_t *) parameters;
@@ -51,6 +54,7 @@ void eth2_plugin_call(eth_plugin_msg_t message, void *parameters) {
5154
ethPluginProvideParameter_t *msg = (ethPluginProvideParameter_t *) parameters;
5255
eth2_deposit_parameters_t *context = (eth2_deposit_parameters_t *) msg->pluginContext;
5356
uint32_t index;
57+
5458
PRINTF("eth2 plugin provide parameter %d %.*H\n",
5559
msg->parameterOffset,
5660
32,

0 commit comments

Comments
 (0)