Actually refer to the base relocation table of our loaded image.
Currently when we process base relocations, we get the correct Data Directory pointer from the headers (context->RelocDir), and that header has been copied into our pristine allocated image when we copied up to SizeOfHeaders. But the data it points to has not been mirrored in to the new image, so it is whatever data AllocPool() gave us. This patch changes relocate_coff() to refer to the base relocation table from the image we loaded from disk, but apply the fixups to the new copy. I have no idea how x86_64 worked without this, but I can't make aarch64 work without it. I also don't know how Ard or Leif have seen aarch64 work. Maybe they haven't? Leif indicated on irc that they may have only tested shim with simple "hello world" applications from gnu-efi; they are certainly much less complex than grub.efi, and are generated through a different linking process. My only theory is that we're getting recycled data there pretty reliably that just makes us /not/ process any relocations, but since our ImageBase is 0, and I don't think we ever load grub with 0 as its base virtual address, that doesn't follow. I'm open to any other ideas anybody has. I do know that on x86_64 (and presumably aarch64 as well), we don't actually start seeing *symptoms* of this bug until the first chunk of 94c9a77f is applied. Once that is applied, relocate_coff() starts seeing zero for both RelocBase->VirtualAddress and RelocBase->SizeOfBlock, because RelocBase is a (generated, relative) pointer that only makes sense in the context of the original binary, not our partial copy. Since RelocBase->SizeOfBlock is tested first, relocate_base() gives us "Reloc block size is invalid" and returns EFI_UNSUPPORTED. At that point shim exits with an error.  The second chunk of 94c9a77f patch makes no difference on this issue.  I don't see why at all.  Which could really be any value since it's AllocatePool() and not AllocateZeroPool() results, but 0 is all I've observed; I think AllocatePool() has simply never recycled any memory in my test cases.  which is silent because perror() tries to avoid talking because that has caused much crashing in the past; work needs to go in to 0.9 for this. Signed-off-by: Peter Jones <firstname.lastname@example.org>
Showing with 21 additions and 21 deletions