Module Name:    src
Committed By:   maxv
Date:           Thu Feb  9 19:30:56 UTC 2017

Modified Files:
        src/sys/arch/amd64/amd64: locore.S

Log Message:
If the preloaded modules cannot be mapped with the initial amount of VA,
discard the associated bootinfo entry. Otherwise the machine faults and
reboots immediately.

I spotted this bug more than a year ago, but I recently saw that there is
already PR/42645 (7 years old), so just fix it. The size has been increased
in the meantime, so the limit is unlikely to be reached anyway.


To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/arch/amd64/amd64/locore.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.120 src/sys/arch/amd64/amd64/locore.S:1.121
--- src/sys/arch/amd64/amd64/locore.S:1.120	Thu Feb  9 08:23:46 2017
+++ src/sys/arch/amd64/amd64/locore.S	Thu Feb  9 19:30:56 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.120 2017/02/09 08:23:46 maxv Exp $	*/
+/*	$NetBSD: locore.S,v 1.121 2017/02/09 19:30:56 maxv Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -211,6 +211,10 @@
   ((NKL4_KIMG_ENTRIES + TABLE_L3_ENTRIES + TABLE_L2_ENTRIES + 1 + UPAGES) \
     * PAGE_SIZE)
 
+/* Amount of VA used to map the kernel, the syms and the preloaded modules */
+#define BOOTMAP_VA_SIZE \
+	(NKL2_KIMG_ENTRIES * (1 << L2_SHIFT) - TABLESIZE - IOM_SIZE)
+
 /*
  * fillkpt - Fill in a kernel page table
  *	eax = pte (page frame | control | status)
@@ -443,7 +447,7 @@ ENTRY(start)
 	testl	%eax,%eax		/* bootinfo = NULL? */
 	jz	bootinfo_finished
 
-	movl	(%eax),%ebx		/* number of entries */
+	movl	(%eax),%ebx		/* bootinfo::bi_nentries */
 	movl	$RELOC(bootinfo),%ebp
 	movl	%ebp,%edx
 	addl	$BOOTINFO_MAXSIZE,%ebp
@@ -462,7 +466,7 @@ bootinfo_entryloop:
 
 	movl	(%ecx),%eax		/* btinfo_common::len (size of entry) */
 	movl	%edx,%edi
-	addl	(%ecx),%edx		/* update dest pointer */
+	addl	%eax,%edx		/* update dest pointer */
 	cmpl	%ebp,%edx		/* beyond bootinfo+BOOTINFO_MAXSIZE? */
 	jg	bootinfo_overflow
 
@@ -470,20 +474,31 @@ bootinfo_entryloop:
 	movl	%eax,%ecx
 
 	/*
-	 * If any modules were loaded, record where they end.  We'll need to
-	 * skip over them.
+	 * If any modules were loaded, record where they end. 'eblob' is used
+	 * later to compute the initial bootstrap tables.
 	 */
 	cmpl	$BTINFO_MODULELIST,4(%esi) /* btinfo_common::type */
-	jne	0f
+	jne	bootinfo_copy
 
-	pushl	12(%esi)		/* btinfo_modulelist::endpa */
-	popl	RELOC(eblob)
+	/* Skip the modules if we won't have enough VA to map them */
+	movl	12(%esi),%eax		/* btinfo_modulelist::endpa */
+	addl	$PGOFSET,%eax		/* roundup to a page */
+	andl	$~PGOFSET,%eax
+	cmpl	$BOOTMAP_VA_SIZE,%eax
+	jg	bootinfo_skip
+	movl	%eax,RELOC(eblob)
 	addl	$KERNBASE_LO,RELOC(eblob)
 	adcl	$KERNBASE_HI,RELOC(eblob)+4
 
-0:
+bootinfo_copy:
 	rep
 	movsb				/* copy esi -> edi */
+	jmp	bootinfo_next
+
+bootinfo_skip:
+	subl	%ecx,%edx		/* revert dest pointer */
+
+bootinfo_next:
 	popl	%eax
 	popl	%esi
 	popl	%edi
@@ -501,8 +516,8 @@ bootinfo_overflow:
 	movl	$RELOC(bootinfo),%ebp
 	movl	%ebp,%edx
 	subl	%ebx,(%edx)		/* correct the number of entries */
-
 bootinfo_finished:
+
 	/* Load 'esym' */
 	movl	16(%esp),%eax
 	testl	%eax,%eax		/* esym = NULL? */

Reply via email to