ImageTool: Update relocation logic

This commit is contained in:
Marvin Häuser 2023-06-03 15:54:08 +02:00 committed by MikhailKrichanov
parent 8db3b2a6a2
commit 8957da50bb
3 changed files with 75 additions and 55 deletions

View File

@ -92,7 +92,6 @@ CheckToolImageSegmentInfo (
return true; return true;
} }
static
const image_tool_segment_t * const image_tool_segment_t *
ImageGetSegmentByAddress ( ImageGetSegmentByAddress (
uint32_t *Address, uint32_t *Address,
@ -117,6 +116,34 @@ ImageGetSegmentByAddress (
return NULL; return NULL;
} }
uint8_t
ToolImageGetRelocSize (
uint8_t Type
)
{
switch (Type) {
case EFI_IMAGE_REL_BASED_HIGHLOW:
{
return sizeof (UINT32);
}
case EFI_IMAGE_REL_BASED_DIR64:
{
return sizeof (UINT64);
}
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
{
return sizeof (UINT32);
}
default:
{
return 0;
}
}
}
static static
bool bool
CheckToolImageReloc ( CheckToolImageReloc (
@ -126,6 +153,7 @@ CheckToolImageReloc (
) )
{ {
uint32_t RelocOffset; uint32_t RelocOffset;
uint8_t RelocSize;
uint32_t RemainingSize; uint32_t RemainingSize;
const image_tool_segment_t *Segment; const image_tool_segment_t *Segment;
uint16_t MovHigh; uint16_t MovHigh;
@ -145,60 +173,40 @@ CheckToolImageReloc (
return false; return false;
} }
switch (Reloc->Type) { RelocSize = ToolImageGetRelocSize (Reloc->Type);
case EFI_IMAGE_REL_BASED_HIGHLOW: if (RelocSize == 0) {
{ raise ();
if (RemainingSize < sizeof (UINT32)) { return false;
raise (); }
return false;
}
break; if (RelocSize > RemainingSize) {
raise ();
return false;
}
if (Reloc->Type == EFI_IMAGE_REL_BASED_ARM_MOV32T) {
if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) {
raise ();
return false;
} }
case EFI_IMAGE_REL_BASED_DIR64: MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset];
{ MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2];
if (RemainingSize < sizeof (UINT64)) { if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) ||
raise (); (MovLow & 0x8000U) != 0) {
return false;
}
break;
}
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
{
if (RemainingSize < sizeof (UINT32)) {
raise ();
return false;
}
if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) {
raise ();
return false;
}
MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset];
MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2];
if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) ||
(MovLow & 0x8000U) != 0) {
raise ();
return false;
}
break;
}
default:
{
raise (); raise ();
return false; return false;
} }
} }
/*if (Segment->Write) { // FIXME: Update drivers?
if ((Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER ||
Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) &&
Segment->Write) {
printf("!!! writable reloc at %x !!!\n", Reloc->Target); printf("!!! writable reloc at %x !!!\n", Reloc->Target);
}*/ //raise ();
//return false;
}
return true; return true;
} }
@ -211,6 +219,7 @@ CheckToolImageRelocInfo (
) )
{ {
const image_tool_reloc_info_t *RelocInfo; const image_tool_reloc_info_t *RelocInfo;
uint32_t PrevTarget;
uint32_t Index; uint32_t Index;
bool Result; bool Result;
@ -222,7 +231,7 @@ CheckToolImageRelocInfo (
return true; return true;
} }
if (RelocInfo->RelocsStripped && (RelocInfo->NumRelocs > 0)) { if (RelocInfo->RelocsStripped) {
raise (); raise ();
return false; return false;
} }
@ -232,14 +241,10 @@ CheckToolImageRelocInfo (
return false; return false;
} }
Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[0]); PrevTarget = 0;
if (!Result) {
raise ();
return false;
}
for (Index = 1; Index < RelocInfo->NumRelocs; ++Index) { for (Index = 0; Index < RelocInfo->NumRelocs; ++Index) {
if (RelocInfo->Relocs[Index].Target < RelocInfo->Relocs[Index - 1].Target) { if (RelocInfo->Relocs[Index].Target < PrevTarget) {
assert (false); assert (false);
return false; return false;
} }
@ -249,6 +254,8 @@ CheckToolImageRelocInfo (
raise (); raise ();
return false; return false;
} }
PrevTarget = RelocInfo->Relocs[Index].Target;
} }
return true; return true;

View File

@ -34,7 +34,7 @@ typedef struct {
uint16_t Machine; uint16_t Machine;
uint16_t Subsystem; uint16_t Subsystem;
uint8_t FixedAddress; uint8_t FixedAddress;
uint8_t Reserved[6]; uint8_t Reserved[7];
} image_tool_header_info_t; } image_tool_header_info_t;
typedef struct { typedef struct {
@ -130,6 +130,11 @@ ToolImageStripRelocs (
image_tool_image_info_t *Image image_tool_image_info_t *Image
); );
uint8_t
ToolImageGetRelocSize (
uint8_t Type
);
RETURN_STATUS RETURN_STATUS
ToolContextConstructUefiImage ( ToolContextConstructUefiImage (
OUT image_tool_image_info_t *Image, OUT image_tool_image_info_t *Image,
@ -176,4 +181,11 @@ ConstructHii (
OUT UINT32 *HiiSize OUT UINT32 *HiiSize
); );
const image_tool_segment_t *
ImageGetSegmentByAddress (
uint32_t *Address,
uint32_t *RemainingSize,
const image_tool_segment_info_t *SegmentInfo
);
#endif // IMAGE_TOOL_H #endif // IMAGE_TOOL_H

View File

@ -138,6 +138,7 @@ ToolImageEmit (
Success = CheckToolImage (&ImageInfo); Success = CheckToolImage (&ImageInfo);
if (!Success) { if (!Success) {
raise ();
ToolImageDestruct (&ImageInfo); ToolImageDestruct (&ImageInfo);
return NULL; return NULL;
} }