diff --git a/tests/multiboot/Makefile b/tests/multiboot/Makefile index 36f01dc647761d39c7b07c6ac2b3ba69d018e50d..ed4225e7d1342fe29ce1959659e66c49aa72fb22 100644 --- a/tests/multiboot/Makefile +++ b/tests/multiboot/Makefile @@ -3,16 +3,26 @@ CCFLAGS=-m32 -Wall -Wextra -Werror -fno-stack-protector -nostdinc -fno-builtin ASFLAGS=-m32 LD=ld -LDFLAGS=-melf_i386 -T link.ld +LDFLAGS_ELF=-melf_i386 -T link.ld +LDFLAGS_BIN=-melf_i386 -T link.ld --oformat=binary LIBS=$(shell $(CC) $(CCFLAGS) -print-libgcc-file-name) -all: mmap.elf modules.elf +AOUT_KLUDGE_BIN=$(foreach x,$(shell seq 1 9),aout_kludge_$x.bin) -mmap.elf: start.o mmap.o libc.o - $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) +all: mmap.elf modules.elf $(AOUT_KLUDGE_BIN) -modules.elf: start.o modules.o libc.o - $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) +mmap.elf: start.o mmap.o libc.o link.ld + $(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS) + +modules.elf: start.o modules.o libc.o link.ld + $(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS) + +aout_kludge_%.bin: aout_kludge_%.o link.ld + $(LD) $(LDFLAGS_BIN) -o $@ $^ $(LIBS) + +.PRECIOUS: aout_kludge_%.o +aout_kludge_%.o: aout_kludge.S + $(CC) $(ASFLAGS) -DSCENARIO=$* -c -o $@ $^ %.o: %.c $(CC) $(CCFLAGS) -c -o $@ $^ diff --git a/tests/multiboot/aout_kludge.S b/tests/multiboot/aout_kludge.S new file mode 100644 index 0000000000000000000000000000000000000000..52e8ebd766b8ea2daac2c46215a3d72a97c6ba68 --- /dev/null +++ b/tests/multiboot/aout_kludge.S @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2018 Kevin Wolf + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +.section multiboot + +#define MB_MAGIC 0x1badb002 +#define MB_FLAGS 0x10000 +#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS) + +.align 4 +.int MB_MAGIC +.int MB_FLAGS +.int MB_CHECKSUM + +#define LAST_BYTE_VALUE 0xa5 + +/* + * Order of fields in the a.out kludge header fields: + * + * header_addr + * load_addr + * load_end_addr + * bss_end_addr + * entry_addr + */ +#if SCENARIO == 1 +/* Well-behaved kernel file with explicit bss_end */ +.int 0x100000 +.int 0x100000 +.int data_end +.int data_end +.int _start +#elif SCENARIO == 2 +/* Well-behaved kernel file with default bss_end */ +.int 0x100000 +.int 0x100000 +.int data_end +.int 0 +.int _start +#elif SCENARIO == 3 +/* Well-behaved kernel file with default load_end */ +.int 0x100000 +.int 0x100000 +.int 0 +.int 0 +.int _start +#elif SCENARIO == 4 +/* Well-behaved kernel file with load_end < data_end and bss > data_end */ +#undef LAST_BYTE_VALUE +#define LAST_BYTE_VALUE 0 +.int 0x100000 +.int 0x100000 +.int code_end +.int 0x140000 +.int _start +#elif SCENARIO == 5 +/* header < load */ +.int 0x10000 +.int 0x100000 +.int data_end +.int data_end +.int _start +#elif SCENARIO == 6 +/* load_end < load */ +.int 0x100000 +.int 0x100000 +.int 0x10000 +.int data_end +.int _start +#elif SCENARIO == 7 +/* header much larger than in reality with default load_end */ +.int 0x80000000 +.int 0x100000 +.int 0 +.int data_end +.int _start +#elif SCENARIO == 8 +/* bss_end < load_end - load (regression test for CVE-2018-7550) */ +.int 0x100000 +.int 0x100000 +.int data_end +.int code_end +.int _start +#elif SCENARIO == 9 +/* Default load_end_addr, load_addr + kernel_file_size > UINT32_MAX */ +.int 0xfffff000 +.int 0xfffff000 +.int 0 +.int 0xfffff001 +.int _start +#else +#error Invalid SCENARIO +#endif + +.section .text +.global _start +_start: + xor %eax, %eax + + cmpb $LAST_BYTE_VALUE, last_byte + je passed + or $0x1, %eax +passed: + + /* Test device exit */ + outl %eax, $0xf4 + + cli + hlt + jmp . +code_end: + +#if SCENARIO != 8 +.space 8192 +#endif + +last_byte: +.byte 0xa5 +data_end: diff --git a/tests/multiboot/aout_kludge.out b/tests/multiboot/aout_kludge.out new file mode 100644 index 0000000000000000000000000000000000000000..031459275b1786934b6e3299d3261bdcf42265e4 --- /dev/null +++ b/tests/multiboot/aout_kludge.out @@ -0,0 +1,42 @@ + + + +=== Running test case: aout_kludge_1.bin === + + + +=== Running test case: aout_kludge_2.bin === + + + +=== Running test case: aout_kludge_3.bin === + + + +=== Running test case: aout_kludge_4.bin === + + + +=== Running test case: aout_kludge_5.bin === + +qemu-system-x86_64: invalid load_addr address + + +=== Running test case: aout_kludge_6.bin === + +qemu-system-x86_64: invalid load_end_addr address + + +=== Running test case: aout_kludge_7.bin === + +qemu-system-x86_64: invalid header_addr address + + +=== Running test case: aout_kludge_8.bin === + +qemu-system-x86_64: invalid bss_end_addr address + + +=== Running test case: aout_kludge_9.bin === + +qemu-system-x86_64: kernel does not fit in address space diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh index bc9c3670afc977684cb71b30b9d71b83fa88dd08..6c33003e716e9428b0cf3ca644ea9223c8dd72be 100755 --- a/tests/multiboot/run_test.sh +++ b/tests/multiboot/run_test.sh @@ -34,7 +34,7 @@ run_qemu() { -device isa-debugcon,chardev=stdio \ -chardev file,path=test.out,id=stdio \ -device isa-debug-exit,iobase=0xf4,iosize=0x4 \ - "$@" + "$@" >> test.log 2>&1 ret=$? cat test.out >> test.log @@ -67,9 +67,15 @@ modules() { run_qemu modules.elf -initrd "module.txt,module.txt argument,module.txt" } +aout_kludge() { + for i in $(seq 1 9); do + run_qemu aout_kludge_$i.bin + done +} + make all -for t in mmap modules; do +for t in mmap modules aout_kludge; do echo > test.log pass=1