svn commit: r190264 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Sun Mar 22 06:42:42 PDT 2009


Author: kib
Date: Sun Mar 22 13:42:41 2009
New Revision: 190264
URL: http://svn.freebsd.org/changeset/base/190264

Log:
  Fix several issues with parsing the notes for ELF objects.
  
  Badly formed ELF note may cause the caclulated pointer to the next note
  to point both after the note region, that was checked in the code, but
  also to point before the region, that was not checked [1]. Remember the
  first note location in note0 and leap out if the note is not between
  note0 and note_end.
  
  In the similar way, badly formed note may cause infinite loop by
  pointing next note into the same or previous note. Guard against this by
  limiting amount of loop iterations by arbitrary choosen big number.
  
  For clarity, check the calculated note alignment in each iteration.
  
  Reported by:	Chris Palmer <chris noncombatant org> [1]
  PR:	kern/132886
  Reviewed and tested by:	dchagin
  MFC after:	3 days

Modified:
  head/sys/kern/imgact_elf.c

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c	Sun Mar 22 13:17:46 2009	(r190263)
+++ head/sys/kern/imgact_elf.c	Sun Mar 22 13:42:41 2009	(r190264)
@@ -1331,7 +1331,7 @@ static boolean_t
 __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote,
     int32_t *osrel)
 {
-	const Elf_Note *note, *note_end;
+	const Elf_Note *note, *note0, *note_end;
 	const Elf_Phdr *phdr, *pnote;
 	const Elf_Ehdr *hdr;
 	const char *note_name;
@@ -1352,12 +1352,12 @@ __elfN(check_note)(struct image_params *
 	    pnote->p_offset + pnote->p_filesz >= PAGE_SIZE)
 		return (FALSE);
 
-	note = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
-	if (!aligned(note, Elf32_Addr))
-		return (FALSE);
+	note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
 	note_end = (const Elf_Note *)(imgp->image_header +
 	    pnote->p_offset + pnote->p_filesz);
-	while (note < note_end) {
+	for (i = 0; i < 100 && note >= note0 && note < note_end; i++) {
+		if (!aligned(note, Elf32_Addr))
+			return (FALSE);
 		if (note->n_namesz != checknote->hdr.n_namesz ||
 		    note->n_descsz != checknote->hdr.n_descsz ||
 		    note->n_type != checknote->hdr.n_type)


More information about the svn-src-all mailing list