[CFT] NDIS optional header length related fixups

Andrew R. Reiter arr at watson.org
Wed Jun 29 19:02:47 GMT 2005


Calling NDIS -CURRENT users,

Attached is a patch that should fix any possible issues with 
mis-calculating offsets or sizes when dealing with anything 
'image_optional_header' related in the PE loading code.  The reason for 
the patch is that the optional header can have a varying length due to the 
lack of requiring the existence of all the 'image_data_directory's to 
exist within a binary.  As far as I can tell, most drivers tend to include 
all, but due to the basic idea that there can be less than 
IMAGE_DIRECTORY_ENTRIES_MAX data directories in the optional header, we 
should at least make an attempt at preemptively catch any bugs that might 
arise due to improper pointer calculation.

If you could, please give it a run in your tree!

The patch is also located at:
   http://www.watson.org/~arr/ndis_opthdrsz.diff

I guess let me know if anyone has any problems with this working (or 
other).

Cheers,
Andrew

--
Andrew R. Reiter
arr at watson.org
-------------- next part --------------
Index: pe_var.h
===================================================================
RCS file: /home/ncvs/src/sys/compat/ndis/pe_var.h,v
retrieving revision 1.13
diff -u -u -r1.13 pe_var.h
--- pe_var.h	11 Apr 2005 02:02:34 -0000	1.13
+++ pe_var.h	29 Jun 2005 18:47:58 -0000
@@ -214,6 +214,10 @@
 
 typedef struct image_nt_header image_nt_header;
 
+#define	IMAGE_SIZEOF_NT_HEADER(nthdr)					\
+	(offsetof(image_nt_header, inh_optionalhdr) +			\
+	  ((image_nt_header *)(nthdr))->inh_filehdr.ifh_optionalhdrlen)
+
 /* Directory Entries */
 
 #define IMAGE_DIRECTORY_ENTRY_EXPORT         0   /* Export Directory */
@@ -281,6 +285,12 @@
 
 #define IMAGE_SIZEOF_SECTION_HEADER          40
 
+#define IMAGE_FIRST_SECTION(nthdr)					\
+	((image_section_header *)((vm_offset_t)(nthdr) +		\
+	  offsetof(image_nt_header, inh_optionalhdr) +			\
+	  ((image_nt_header *)(nthdr))->inh_filehdr.ifh_optionalhdrlen))
+
+
 /*
  * Import format
  */
Index: subr_pe.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/ndis/subr_pe.c,v
retrieving revision 1.11
diff -u -u -r1.11 subr_pe.c
--- subr_pe.c	24 Feb 2005 17:58:27 -0000	1.11
+++ subr_pe.c	29 Jun 2005 18:47:58 -0000
@@ -142,7 +142,7 @@
 	nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
 
 	bcopy ((char *)&nt_hdr->inh_optionalhdr, (char *)hdr,
-	    sizeof(image_optional_header));
+	    nt_hdr->inh_filehdr.ifh_optionalhdrlen);
 
 	return(0);
 }
@@ -170,8 +170,7 @@
 	nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
 
 	bcopy ((char *)&nt_hdr->inh_filehdr, (char *)hdr,
-	    sizeof(image_file_header));
-
+	    IMAGE_SIZEOF_NT_HEADER(nt_hdr));
 	return(0);
 }
 
@@ -197,8 +196,7 @@
 
 	dos_hdr = (image_dos_header *)imgbase;
 	nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
-	sect_hdr = (image_section_header *)((vm_offset_t)nt_hdr +
-	    sizeof(image_nt_header));
+	sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
 
 	bcopy ((char *)sect_hdr, (char *)hdr, sizeof(image_section_header));
 
@@ -280,8 +278,7 @@
 
 	dos_hdr = (image_dos_header *)imgbase;
 	nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
-	sect_hdr = (image_section_header *)((vm_offset_t)nt_hdr +
-	    sizeof(image_nt_header));
+	sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
 
 	/*
 	 * The test here is to see if the RVA falls somewhere
@@ -339,8 +336,7 @@
 
 	dos_hdr = (image_dos_header *)imgbase;
 	nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
-	sect_hdr = (image_section_header *)((vm_offset_t)nt_hdr +
-	    sizeof(image_nt_header));
+	sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
 
 	for (i = 0; i < sections; i++) {
 		if (!strcmp ((char *)&sect_hdr->ish_name, name)) {


More information about the freebsd-current mailing list