[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 *)§_hdr->ish_name, name)) {
More information about the freebsd-current
mailing list