ImageTool: Handle image address overflows

This commit is contained in:
Marvin Häuser 2023-06-13 02:17:36 +02:00 committed by MikhailKrichanov
parent 78703654d8
commit b25125e0e1
3 changed files with 27 additions and 7 deletions

View File

@ -105,6 +105,11 @@ CheckToolImageHeaderInfo (
return false; return false;
} }
if (HeaderInfo->BaseAddress + ImageSize < HeaderInfo->BaseAddress) {
DEBUG_RAISE ();
return false;
}
return true; return true;
} }
@ -161,7 +166,6 @@ static
bool bool
CheckToolImageReloc ( CheckToolImageReloc (
const image_tool_image_info_t *Image, const image_tool_image_info_t *Image,
uint32_t ImageSize,
const image_tool_reloc_t *Reloc const image_tool_reloc_t *Reloc
) )
{ {
@ -224,8 +228,7 @@ CheckToolImageReloc (
static static
bool bool
CheckToolImageRelocInfo ( CheckToolImageRelocInfo (
const image_tool_image_info_t *Image, const image_tool_image_info_t *Image
uint32_t ImageSize
) )
{ {
const image_tool_reloc_info_t *RelocInfo; const image_tool_reloc_info_t *RelocInfo;
@ -310,7 +313,7 @@ CheckToolImage (
return false; return false;
} }
Result = CheckToolImageRelocInfo (Image, ImageSize); Result = CheckToolImageRelocInfo (Image);
if (!Result) { if (!Result) {
DEBUG_RAISE (); DEBUG_RAISE ();
return false; return false;
@ -371,9 +374,12 @@ ToolImageDestruct (
bool bool
ToolImageRelocate ( ToolImageRelocate (
image_tool_image_info_t *Image, image_tool_image_info_t *Image,
uint64_t BaseAddress uint64_t BaseAddress,
uint32_t IgnorePrefix
) )
{ {
const image_tool_segment_t *LastSegment;
uint32_t ImageSize;
uint64_t Adjust; uint64_t Adjust;
const image_tool_reloc_t *Reloc; const image_tool_reloc_t *Reloc;
uint32_t RelocOffset; uint32_t RelocOffset;
@ -394,6 +400,19 @@ ToolImageRelocate (
return true; return true;
} }
LastSegment = &Image->SegmentInfo.Segments[Image->SegmentInfo.NumSegments - 1];
ImageSize = LastSegment->ImageAddress + LastSegment->ImageSize;
//
// When removing the image header prefix, BaseAddress + ImageSize may indeed
// overflow. The important part is that the address starting from the first
// image segment does not.
//
if (BaseAddress + ImageSize < BaseAddress + IgnorePrefix) {
DEBUG_RAISE ();
return false;
}
for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) {
Reloc = &Image->RelocInfo.Relocs[Index]; Reloc = &Image->RelocInfo.Relocs[Index];

View File

@ -110,7 +110,8 @@ ImageInitUnpaddedSize (
bool bool
ToolImageRelocate ( ToolImageRelocate (
image_tool_image_info_t *Image, image_tool_image_info_t *Image,
uint64_t BaseAddress uint64_t BaseAddress,
uint32_t IgnorePrefix
); );
void void

View File

@ -145,7 +145,7 @@ ToolImageEmit (
} }
if (Relocate) { if (Relocate) {
Success = ToolImageRelocate (&ImageInfo, BaseAddress); Success = ToolImageRelocate (&ImageInfo, BaseAddress, 0);
if (!Success) { if (!Success) {
fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath); fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath);
ToolImageDestruct (&ImageInfo); ToolImageDestruct (&ImageInfo);