Skip to content

Commit

Permalink
fix(save_segment): Adds segment len check the same as bootloader does
Browse files Browse the repository at this point in the history
  • Loading branch information
KonstantinKondrashov committed Dec 12, 2024
1 parent 7681ec0 commit a6bceb7
Showing 1 changed file with 21 additions and 7 deletions.
28 changes: 21 additions & 7 deletions esptool/bin_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,24 @@ def maybe_patch_segment_data(self, f, segment_data):
)
return segment_data

def save_segment(self, f, segment, checksum=None):
def save_segment(self, f, segment, checksum=None, segment_name=None):
"""
Save the next segment to the image file,
return next checksum value if provided
"""
segment_data = self.maybe_patch_segment_data(f, segment.data)
f.write(struct.pack("<II", segment.addr, len(segment_data)))
segment_len = len(segment_data)
segment_name = segment_name if segment_name is not None else ""
if segment_len & 3:
raise FatalError(
f"Invalid {segment_name} segment length {segment_len:#x}. It has to be multiple of 4."
)
SIXTEEN_MB = 0x1000000
if segment_len >= SIXTEEN_MB:
raise FatalError(
f"Invalid {segment_name} segment length {segment_len:#x}. The 16 MB limit has been exceeded."
)
f.write(struct.pack("<II", segment.addr, segment_len))
f.write(segment_data)
if checksum is not None:
return ESPLoader.checksum(segment_data, checksum)
Expand All @@ -293,7 +304,8 @@ def save_flash_segment(self, f, segment, checksum=None):
segment_len_remainder = segment_end_pos % self.IROM_ALIGN
if segment_len_remainder < 0x24:
segment.data += b"\x00" * (0x24 - segment_len_remainder)
return self.save_segment(f, segment, checksum)
segment_name = getattr(segment, "name", None)
return self.save_segment(f, segment, checksum, segment_name)

def read_checksum(self, f):
"""Return ESPLoader checksum from end of just-read image"""
Expand Down Expand Up @@ -748,7 +760,7 @@ def get_alignment_data_needed(segment):
# and checksum (ROM bootloader will only care for RAM segments and its
# correct checksums)
for segment in ram_segments:
checksum = self.save_segment(f, segment, checksum)
checksum = self.save_segment(f, segment, checksum, segment.name)
total_segments += 1
self.append_checksum(f, checksum)

Expand All @@ -769,7 +781,7 @@ def get_alignment_data_needed(segment):

pad_len -= self.ROM_LOADER.BOOTLOADER_FLASH_OFFSET
pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell())
self.save_segment(f, pad_segment)
self.save_segment(f, pad_segment, None, segment.name)
total_segments += 1
# check the alignment
assert (f.tell() + 8 + self.ROM_LOADER.BOOTLOADER_FLASH_OFFSET) % (
Expand All @@ -793,7 +805,9 @@ def get_alignment_data_needed(segment):
ram_segments.pop(0)
else:
pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell())
checksum = self.save_segment(f, pad_segment, checksum)
checksum = self.save_segment(
f, pad_segment, checksum, segment.name
)
total_segments += 1
else:
# write the flash segment
Expand All @@ -806,7 +820,7 @@ def get_alignment_data_needed(segment):

# flash segments all written, so write any remaining RAM segments
for segment in ram_segments:
checksum = self.save_segment(f, segment, checksum)
checksum = self.save_segment(f, segment, checksum, segment.name)
total_segments += 1

if self.secure_pad:
Expand Down

0 comments on commit a6bceb7

Please sign in to comment.