Module Name:    src
Committed By:   maxv
Date:           Tue May  5 19:26:47 UTC 2020

Modified Files:
        src/sys/arch/amd64/stand/prekern: elf.c prekern.h

Log Message:
Gather the section filtering in a single function, and add a sanity check
when relocating, to make sure the section we're accessing is mappable.

Currently this check fails, because of the Xen section, which has RELAs but
is an unmappable unallocated note.

Also improve the prekern ASSERTs while here.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/amd64/stand/prekern/elf.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/amd64/stand/prekern/prekern.h

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/stand/prekern/elf.c
diff -u src/sys/arch/amd64/stand/prekern/elf.c:1.18 src/sys/arch/amd64/stand/prekern/elf.c:1.19
--- src/sys/arch/amd64/stand/prekern/elf.c:1.18	Sat Jan  5 22:11:07 2019
+++ src/sys/arch/amd64/stand/prekern/elf.c	Tue May  5 19:26:47 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: elf.c,v 1.18 2019/01/05 22:11:07 maxv Exp $	*/
+/*	$NetBSD: elf.c,v 1.19 2020/05/05 19:26:47 maxv Exp $	*/
 
 /*
  * Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
@@ -259,6 +259,19 @@ elf_build_head(vaddr_t headva)
 	}
 }
 
+static bool
+elf_section_mappable(Elf_Shdr *shdr)
+{
+	if (!(shdr->sh_flags & SHF_ALLOC)) {
+		return false;
+	}
+	if (shdr->sh_type != SHT_NOBITS &&
+	    shdr->sh_type != SHT_PROGBITS) {
+		return false;
+	}
+	return true;
+}
+
 void
 elf_map_sections(void)
 {
@@ -273,11 +286,7 @@ elf_map_sections(void)
 	for (i = 0; i < eif.ehdr->e_shnum; i++) {
 		shdr = &eif.shdr[i];
 
-		if (!(shdr->sh_flags & SHF_ALLOC)) {
-			continue;
-		}
-		if (shdr->sh_type != SHT_NOBITS &&
-		    shdr->sh_type != SHT_PROGBITS) {
+		if (!elf_section_mappable(shdr)) {
 			continue;
 		}
 
@@ -383,10 +392,10 @@ elf_kernel_reloc(void)
 	 * Update all symbol values with the appropriate offset.
 	 */
 	for (i = 0; i < eif.ehdr->e_shnum; i++) {
-		if (eif.shdr[i].sh_type != SHT_NOBITS &&
-		    eif.shdr[i].sh_type != SHT_PROGBITS) {
+		if (!elf_section_mappable(&eif.shdr[i])) {
 			continue;
 		}
+
 		ASSERT(eif.shdr[i].sh_offset != 0);
 		secva = baseva + eif.shdr[i].sh_offset;
 		for (j = 0; j < eif.symcnt; j++) {
@@ -417,7 +426,10 @@ elf_kernel_reloc(void)
 
 		secidx = eif.shdr[i].sh_info;
 		if (secidx >= eif.ehdr->e_shnum) {
-			fatal("elf_kernel_reloc: wrong REL relocation");
+			fatal("elf_kernel_reloc: REL sh_info is malformed");
+		}
+		if (!elf_section_mappable(&eif.shdr[secidx])) {
+			fatal("elf_kernel_reloc: REL sh_info not mappable");
 		}
 		base = (uintptr_t)eif.ehdr + eif.shdr[secidx].sh_offset;
 
@@ -446,7 +458,10 @@ elf_kernel_reloc(void)
 
 		secidx = eif.shdr[i].sh_info;
 		if (secidx >= eif.ehdr->e_shnum) {
-			fatal("elf_kernel_reloc: wrong RELA relocation");
+			fatal("elf_kernel_reloc: RELA sh_info is malformed");
+		}
+		if (!elf_section_mappable(&eif.shdr[secidx])) {
+			fatal("elf_kernel_reloc: RELA sh_info not mappable");
 		}
 		base = (uintptr_t)eif.ehdr + eif.shdr[secidx].sh_offset;
 

Index: src/sys/arch/amd64/stand/prekern/prekern.h
diff -u src/sys/arch/amd64/stand/prekern/prekern.h:1.20 src/sys/arch/amd64/stand/prekern/prekern.h:1.21
--- src/sys/arch/amd64/stand/prekern/prekern.h:1.20	Wed Jun 20 11:49:37 2018
+++ src/sys/arch/amd64/stand/prekern/prekern.h	Tue May  5 19:26:47 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: prekern.h,v 1.20 2018/06/20 11:49:37 maxv Exp $	*/
+/*	$NetBSD: prekern.h,v 1.21 2020/05/05 19:26:47 maxv Exp $	*/
 
 /*
  * Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
@@ -37,7 +37,7 @@
 #include "pdir.h"
 #include "redef.h"
 
-#define ASSERT(a) if (!(a)) fatal("ASSERT");
+#define ASSERT(a) if (!(a)) fatal("ASSERT: " #a);
 typedef uint64_t pte_prot_t;
 #define WHITE_ON_BLACK 0x07
 #define RED_ON_BLACK 0x04

Reply via email to