From cf75e3e8e4019a302ef808c31090b52fb546feb0 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Mon, 2 Jan 2017 15:34:21 +0800
Subject: [PATCH] server: All fields up to CheckSum are mandatory regardless of
 SizeOfOptionalHeader value.

---
 server/mapping.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/server/mapping.c b/server/mapping.c
index 37c17b0..9f7cd7b 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -588,11 +588,10 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
     mz_size = size;
     pos = mz.dos.e_lfanew;
 
+    /* zero out header in the case it's not present or partial */
+    memset( &nt, 0, sizeof(nt) );
     size = pread( unix_fd, &nt, sizeof(nt), pos );
     if (size < sizeof(nt.Signature) + sizeof(nt.FileHeader)) return STATUS_INVALID_IMAGE_FORMAT;
-    /* zero out Optional header in the case it's not present or partial */
-    size = min( size, sizeof(nt.Signature) + sizeof(nt.FileHeader) + nt.FileHeader.SizeOfOptionalHeader );
-    if (size < sizeof(nt)) memset( (char *)&nt + size, 0, sizeof(nt) - size );
     if (nt.Signature != IMAGE_NT_SIGNATURE)
     {
         IMAGE_OS2_HEADER *os2 = (IMAGE_OS2_HEADER *)&nt;
@@ -605,6 +604,10 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
     switch (nt.opt.hdr32.Magic)
     {
     case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+        /* All fields up to CheckSum are mandatory regardless of SizeOfOptionalHeader value */
+        size = max( nt.FileHeader.SizeOfOptionalHeader, offsetof(IMAGE_OPTIONAL_HEADER32, CheckSum) );
+        if (size < sizeof(nt.opt.hdr32)) memset( (char *)&nt.opt.hdr32 + size, 0, sizeof(nt.opt.hdr32) - size );
+
         switch (nt.FileHeader.Machine)
         {
         case IMAGE_FILE_MACHINE_I386:
@@ -650,6 +653,10 @@ static unsigned int get_image_params( struct mapping *mapping, file_pos_t file_s
         break;
 
     case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+        /* All fields up to CheckSum are mandatory regardless of SizeOfOptionalHeader value */
+        size = max( nt.FileHeader.SizeOfOptionalHeader, offsetof(IMAGE_OPTIONAL_HEADER64, CheckSum) );
+        if (size < sizeof(nt.opt.hdr64)) memset( (char *)&nt.opt.hdr64 + size, 0, sizeof(nt.opt.hdr64) - size );
+
         if (!(cpu_mask & CPU_64BIT_MASK)) return STATUS_INVALID_IMAGE_WIN_64;
         switch (nt.FileHeader.Machine)
         {
-- 
1.9.1

