svn commit: r248587 - stable/9/sys/kern

Tijl Coosemans tijl at FreeBSD.org
Thu Mar 21 16:15:35 UTC 2013


Author: tijl
Date: Thu Mar 21 16:15:34 2013
New Revision: 248587
URL: http://svnweb.freebsd.org/changeset/base/248587

Log:
  - Fix two possible overflows when testing if ELF program headers are on
    the first page:
    1. Cast uint16_t operands in a multiplication to unsigned int because
       otherwise the implicit promotion to int results in a signed
       multiplication that can overflow and the behaviour on integer
       overflow is undefined.
    2. Replace (offset + size > PAGE_SIZE) with (size > PAGE_SIZE - offset)
       because the sum may overflow.
  - Use the same tests to see if the path to the interpreter is on the first
    page. There's no overflow here because size is already limited by
    MAXPATHLEN, but the compiler optimises the new tests better. Also fix an
    off-by-one error.
  - Simplify tests to see if an ELF note program header is on the first page.
    This also fixes an off-by-one error.
  
  Reviewed by:	kib

Modified:
  stable/9/sys/kern/imgact_elf.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/imgact_elf.c
==============================================================================
--- stable/9/sys/kern/imgact_elf.c	Thu Mar 21 16:04:34 2013	(r248586)
+++ stable/9/sys/kern/imgact_elf.c	Thu Mar 21 16:15:34 2013	(r248587)
@@ -663,9 +663,8 @@ __elfN(load_file)(struct proc *p, const 
 	}
 
 	/* Only support headers that fit within first page for now      */
-	/*    (multiplication of two Elf_Half fields will not overflow) */
 	if ((hdr->e_phoff > PAGE_SIZE) ||
-	    (hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE - hdr->e_phoff) {
+	    (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
 		error = ENOEXEC;
 		goto fail;
 	}
@@ -747,7 +746,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
 	 */
 
 	if ((hdr->e_phoff > PAGE_SIZE) ||
-	    (hdr->e_phoff + hdr->e_phentsize * hdr->e_phnum) > PAGE_SIZE) {
+	    (u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
 		/* Only support headers in first page for now */
 		return (ENOEXEC);
 	}
@@ -766,8 +765,8 @@ __CONCAT(exec_, __elfN(imgact))(struct i
 		case PT_INTERP:
 			/* Path to interpreter */
 			if (phdr[i].p_filesz > MAXPATHLEN ||
-			    phdr[i].p_offset >= PAGE_SIZE ||
-			    phdr[i].p_offset + phdr[i].p_filesz >= PAGE_SIZE)
+			    phdr[i].p_offset > PAGE_SIZE ||
+			    phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset)
 				return (ENOEXEC);
 			interp = imgp->image_header + phdr[i].p_offset;
 			interp_name_len = phdr[i].p_filesz;
@@ -1555,9 +1554,8 @@ __elfN(parse_notes)(struct image_params 
 	const char *note_name;
 	int i;
 
-	if (pnote == NULL || pnote->p_offset >= PAGE_SIZE ||
-	    pnote->p_filesz > PAGE_SIZE ||
-	    pnote->p_offset + pnote->p_filesz >= PAGE_SIZE)
+	if (pnote == NULL || pnote->p_offset > PAGE_SIZE ||
+	    pnote->p_filesz > PAGE_SIZE - pnote->p_offset)
 		return (FALSE);
 
 	note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset);


More information about the svn-src-all mailing list