Hi all,
Here is a PoC of NULL pointer dereference checking in coreboot x86. It is
surprisingly easy to implement.
It uses strange expand down segments, making a data segment from 4KB-4GB (with
base 0). It should catch most NULL derefence symbols. Unfortunately we access
0x500 while placing the coreboot tables. The hack in the patch just swaps the ds
selector work arounding that.
More advanced method would use paging and PAE, first 4MB with 4KB pages rest
with 4MB pages identity mapped. We could even mark other than coreboot RAM range
as "missing" allowing more fine grained tests what is where accessed.
Even the segment hack above could be used to check the stack overflows, but I
think we will need in IDT instead of interrupt gate a task gate and set there a
exception stack, otherwise it will end very badly while CPU is trying to safe
stack yet again during the exception.
PS: Qemu does not implement segment limit checking, so just try on real HW. Dont
forget to switch off GDB debugging otherwise you wont get human readable
exception notice, on the other hand you can try to debug that ;)
Thanks,
Rudolf
diff --git a/src/arch/x86/boot/coreboot_table.c b/src/arch/x86/boot/coreboot_table.c
index db3a8a9..64f4226 100644
--- a/src/arch/x86/boot/coreboot_table.c
+++ b/src/arch/x86/boot/coreboot_table.c
@@ -509,6 +509,9 @@ unsigned long write_coreboot_table(
struct lb_memory *mem;
#if CONFIG_WRITE_HIGH_TABLES == 1
+
+ asm volatile (" movw $0x20, %%ax \n movw %%ax, %%ds" ::: "eax") ;
+
printk(BIOS_DEBUG, "Writing high table forward entry at 0x%08lx\n",
low_table_end);
head = lb_table_init(low_table_end);
@@ -537,6 +540,7 @@ unsigned long write_coreboot_table(
low_table_end += 0xfff; // 4K aligned
low_table_end &= ~0xfff;
printk(BIOS_DEBUG, "0x%08lx \n", low_table_end);
+ asm volatile (" movw $0x18, %%ax \n movw %%ax, %%ds" ::: "eax") ;
/* The Linux kernel assumes this region is reserved */
printk(BIOS_DEBUG, "Adjust rom_table_end from 0x%08lx to ", rom_table_end);
diff --git a/src/arch/x86/lib/c_start.S b/src/arch/x86/lib/c_start.S
index 005ac33..9fd4987 100644
--- a/src/arch/x86/lib/c_start.S
+++ b/src/arch/x86/lib/c_start.S
@@ -276,14 +276,14 @@ gdt:
.word 0xffff, 0x0000
.byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */
- /* selgdt 0x18, flat data segment */
+ /* selgdt 0x18, flat data segment, 4KB - 4GB */
+ .word 0x0000, 0x0000
+ .byte 0x00, 0x96, 0xc0, 0x00
+
+ /* selgdt 0x20, flat data segment */
.word 0xffff, 0x0000
.byte 0x00, 0x93, 0xcf, 0x00
- /* selgdt 0x20, unused */
- .word 0x0000, 0x0000 /* dummy */
- .byte 0x00, 0x00, 0x00, 0x00
-
/* The next two entries are used for executing VGA option ROMs */
/* selgdt 0x28 16 bit 64k code at 0x00000000 */
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot