Date: Wed, 29 Jun 2005 15:06:52 -0400 (EDT) From: "Andrew R. Reiter" <arr@watson.org> To: freebsd-current@FreeBSD.org Subject: [CFT] NDIS optional header length related fixups Message-ID: <20050629145451.J85841@fledge.watson.org>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] 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@watson.org [-- Attachment #2 --] 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)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050629145451.J85841>
