Skip to content

Commit 70243e1

Browse files
committed
fix(sd): cap the size of files read into memory
sd_card_read_file() allocated whatever st_size reported, so a hostile card could make the device chase a multi-gigabyte read before anything looked at the content. Everything read this way is a descriptor, a PSBT or a mnemonic backup, all far below the 1 MB cap.
1 parent c90d669 commit 70243e1

3 files changed

Lines changed: 15 additions & 1 deletion

File tree

components/sd_card/include/sd_card.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ esp_err_t sd_card_remount(void);
2828
bool sd_card_is_mounted(void);
2929

3030
esp_err_t sd_card_write_file(const char *path, const uint8_t *data, size_t len);
31+
32+
/* Largest file sd_card_read_file() will pull into memory. Everything read
33+
* this way is a descriptor, a PSBT or a mnemonic backup; the biggest of those
34+
* is a PSBT carrying a full previous transaction per input, which stays far
35+
* below this. Anything larger is refused with ESP_ERR_INVALID_SIZE rather
36+
* than allocated, so a hostile card cannot make the device chase a multi-
37+
* gigabyte read before anything looks at the content. */
38+
#define SD_CARD_MAX_READ_LEN (1024u * 1024u)
39+
3140
esp_err_t sd_card_read_file(const char *path, uint8_t **data_out,
3241
size_t *len_out);
3342
esp_err_t sd_card_file_size(const char *path, size_t *size_out);

components/sd_card/src/sd_card.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ esp_err_t sd_card_read_file(const char *path, uint8_t **data_out,
226226
return ESP_ERR_NOT_FOUND;
227227
if (st.st_size == 0)
228228
return ESP_OK;
229+
if (st.st_size < 0 || (uintmax_t)st.st_size > SD_CARD_MAX_READ_LEN)
230+
return ESP_ERR_INVALID_SIZE;
229231

230232
uint8_t *buffer = malloc(st.st_size);
231233
if (!buffer)

main/pages/load/load.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ static void load_on_file_selected(const char *full_path, const char *dir,
3636
esp_err_t ret = sd_card_read_file(full_path, &data, &len);
3737
if (ret != ESP_OK || !data || len == 0) {
3838
free(data);
39-
dialog_show_error_timeout("Failed to read file", NULL, 0);
39+
dialog_show_error_timeout(ret == ESP_ERR_INVALID_SIZE
40+
? "File is too large"
41+
: "Failed to read file",
42+
NULL, 0);
4043
return;
4144
}
4245

0 commit comments

Comments
 (0)