Skip to content

Commit 4c4b484

Browse files
committed
Improve checking for malicious flash data
Add data_max_size to prevent overwriting the bootloader with data from flash
1 parent 46aed89 commit 4c4b484

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

bootloaders/encrypted/enc_bootloader.c

+16-6
Original file line numberDiff line numberDiff line change
@@ -92,38 +92,48 @@ int main() {
9292

9393
rc = rom_get_partition_table_info((uint32_t*)workarea, 0x8, PT_INFO_PARTITION_LOCATION_AND_FLAGS | PT_INFO_SINGLE_PARTITION | (boot_partition << 24));
9494

95-
uint32_t data_start_addr;
96-
uint32_t data_end_addr;
95+
uint32_t data_start_addr = 0;
96+
uint32_t data_end_addr = 0;
97+
uint32_t data_max_size = 0;
9798
if (rc != 3) {
9899
printf("No boot partition - assuming bin at start of flash\n");
99100
data_start_addr = 0;
100101
data_end_addr = 0x70000; // must fit into 0x20000000 -> 0x20070000
102+
data_max_size = data_end_addr - data_start_addr;
101103
} else {
102104
uint16_t first_sector_number = (((uint32_t*)workarea)[1] & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB;
103105
uint16_t last_sector_number = (((uint32_t*)workarea)[1] & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB;
104106
data_start_addr = first_sector_number * 0x1000;
105107
data_end_addr = (last_sector_number + 1) * 0x1000;
108+
data_max_size = data_end_addr - data_start_addr;
106109

107-
printf("Partition Start %x, End %x\n", data_start_addr, data_end_addr);
110+
printf("Partition Start %x, End %x, Max Size %x\n", data_start_addr, data_end_addr, data_max_size);
108111
}
109112

110113
printf("Decrypting the chosen image\n");
111114
uint32_t first_mb_start = 0;
115+
bool first_mb_start_found = false;
112116
uint32_t first_mb_end = 0;
113117
uint32_t last_mb_start = 0;
114-
for (uint16_t i=0; i <= 0x1000; i += 4) {
118+
for (uint16_t i=0; i < 0x1000; i += 4) {
115119
if (*(uint32_t*)(XIP_BASE + data_start_addr + i) == 0xffffded3) {
116120
printf("Found first block start\n");
117121
first_mb_start = i;
118-
}
119-
if (*(uint32_t*)(XIP_BASE + data_start_addr + i) == 0xab123579) {
122+
first_mb_start_found = true;
123+
} else if (first_mb_start_found && (*(uint32_t*)(XIP_BASE + data_start_addr + i) == 0xab123579)) {
120124
printf("Found first block end\n");
121125
first_mb_end = i + 4;
122126
last_mb_start = *(uint32_t*)(XIP_BASE + data_start_addr + i-4) + first_mb_start;
123127
break;
124128
}
125129
}
126130

131+
if (last_mb_start > data_max_size) {
132+
// todo - harden this check
133+
printf("ERROR: Encrypted binary is too big for it's partition - resetting\n");
134+
reset_usb_boot(0, 0);
135+
}
136+
127137
if (*(uint32_t*)(XIP_BASE + data_start_addr + last_mb_start) == 0xffffded3) {
128138
printf("Found last block start where expected\n");
129139
} else {

0 commit comments

Comments
 (0)