The base address is in the pe32_opt_hdr, not after it.

Previous to commit f7f42accbbbb the base was read standalone (as the first
field of pe32_opt_hdr).  However with the addition of reading the full
contents of pe32_opt_hdr, such read will also fetch the base.  The current
attempt to read the base after pe32_opt_hdr is bogus, and could only work
if the file cursor is repositioned using lseek(), but there's no need for
that as the data is already fetched in pe32_opt_hdr.

Fixes: f7f42accbbbb ('x86/efi: Use generic PE/COFF structures')
Signed-off-by: Roger Pau Monné <roger....@citrix.com>
---
 xen/arch/x86/efi/mkreloc.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/efi/mkreloc.c b/xen/arch/x86/efi/mkreloc.c
index 375cb79d6959..1a6cfc845cba 100644
--- a/xen/arch/x86/efi/mkreloc.c
+++ b/xen/arch/x86/efi/mkreloc.c
@@ -35,7 +35,6 @@ static unsigned int load(const char *name, int *handle,
     struct mz_hdr mz_hdr;
     struct pe_hdr pe_hdr;
     struct pe32_opt_hdr pe32_opt_hdr;
-    uint32_t base;
 
     if ( in < 0 ||
          read(in, &mz_hdr, sizeof(mz_hdr)) != sizeof(mz_hdr) )
@@ -55,7 +54,6 @@ static unsigned int load(const char *name, int *handle,
     if ( lseek(in, mz_hdr.peaddr, SEEK_SET) < 0 ||
          read(in, &pe_hdr, sizeof(pe_hdr)) != sizeof(pe_hdr) ||
          read(in, &pe32_opt_hdr, sizeof(pe32_opt_hdr)) != sizeof(pe32_opt_hdr) 
||
-         read(in, &base, sizeof(base)) != sizeof(base) ||
          /*
           * Luckily the image size field lives at the
           * same offset for both formats.
@@ -73,11 +71,12 @@ static unsigned int load(const char *name, int *handle,
     {
     case PE_OPT_MAGIC_PE32:
         *width = 32;
-        *image_base = base;
+        *image_base = pe32_opt_hdr.image_base;
         break;
     case PE_OPT_MAGIC_PE32PLUS:
         *width = 64;
-        *image_base = ((uint64_t)base << 32) | pe32_opt_hdr.data_base;
+        *image_base = ((uint64_t)pe32_opt_hdr.image_base << 32) |
+                      pe32_opt_hdr.data_base;
         break;
     default:
         fprintf(stderr, "%s: Wrong PE file format\n", name);
-- 
2.48.1


Reply via email to