On 18/05/20 12:31, Philippe Mathieu-Daudé wrote: > Trying libFuzzer on the vmport device, we get: > > AddressSanitizer:DEADLYSIGNAL > ================================================================= > ==29476==ERROR: AddressSanitizer: SEGV on unknown address 0x000000008840 > (pc 0x56448bec4d79 bp 0x7ffeec9741b0 sp 0x7ffeec9740e0 T0) > ==29476==The signal is caused by a READ memory access. > #0 0x56448bec4d78 in vmport_ioport_read (qemu-fuzz-i386+0x1260d78) > #1 0x56448bb5f175 in memory_region_read_accessor (qemu-fuzz-i386+0xefb175) > #2 0x56448bb30c13 in access_with_adjusted_size (qemu-fuzz-i386+0xeccc13) > #3 0x56448bb2ea27 in memory_region_dispatch_read1 > (qemu-fuzz-i386+0xecaa27) > #4 0x56448bb2e443 in memory_region_dispatch_read (qemu-fuzz-i386+0xeca443) > #5 0x56448b961ab1 in flatview_read_continue (qemu-fuzz-i386+0xcfdab1) > #6 0x56448b96336d in flatview_read (qemu-fuzz-i386+0xcff36d) > #7 0x56448b962ec4 in address_space_read_full (qemu-fuzz-i386+0xcfeec4) > > This is easily reproducible using: > > $ echo inb 0x5658 | qemu-system-i386 -M isapc,accel=qtest -qtest stdio > [I 1589796572.009763] OPENED > [R +0.008069] inb 0x5658 > Segmentation fault (core dumped) > > $ coredumpctl gdb -q > Program terminated with signal SIGSEGV, Segmentation fault. > #0 0x00005605b54d0f21 in vmport_ioport_read (opaque=0x5605b7531ce0, > addr=0, size=4) at hw/i386/vmport.c:77 > 77 eax = env->regs[R_EAX]; > (gdb) p cpu > $1 = (X86CPU *) 0x0 > (gdb) bt > #0 0x00005605b54d0f21 in vmport_ioport_read (opaque=0x5605b7531ce0, > addr=0, size=4) at hw/i386/vmport.c:77 > #1 0x00005605b53db114 in memory_region_read_accessor (mr=0x5605b7531d80, > addr=0, value=0x7ffc9d261a30, size=4, shift=0, mask=4294967295, attrs=...) at > memory.c:434 > #2 0x00005605b53db5d4 in access_with_adjusted_size (addr=0, > value=0x7ffc9d261a30, size=1, access_size_min=4, access_size_max=4, access_fn= > 0x5605b53db0d2 <memory_region_read_accessor>, mr=0x5605b7531d80, > attrs=...) at memory.c:544 > #3 0x00005605b53de156 in memory_region_dispatch_read1 (mr=0x5605b7531d80, > addr=0, pval=0x7ffc9d261a30, size=1, attrs=...) at memory.c:1396 > #4 0x00005605b53de228 in memory_region_dispatch_read (mr=0x5605b7531d80, > addr=0, pval=0x7ffc9d261a30, op=MO_8, attrs=...) at memory.c:1424 > #5 0x00005605b537c80a in flatview_read_continue (fv=0x5605b7650290, > addr=22104, attrs=..., ptr=0x7ffc9d261b4b, len=1, addr1=0, l=1, > mr=0x5605b7531d80) at exec.c:3200 > #6 0x00005605b537c95d in flatview_read (fv=0x5605b7650290, addr=22104, > attrs=..., buf=0x7ffc9d261b4b, len=1) at exec.c:3239 > #7 0x00005605b537c9e6 in address_space_read_full (as=0x5605b5f74ac0 > <address_space_io>, addr=22104, attrs=..., buf=0x7ffc9d261b4b, len=1) at > exec.c:3252 > #8 0x00005605b53d5a5d in address_space_read (len=1, buf=0x7ffc9d261b4b, > attrs=..., addr=22104, as=0x5605b5f74ac0 <address_space_io>) at > include/exec/memory.h:2401 > #9 0x00005605b53d5a5d in cpu_inb (addr=22104) at ioport.c:88 > > X86CPU is NULL because QTest accelerator does not use CPU. > Fix by returning default values when QTest accelerator is used. > > Reported-by: Clang AddressSanitizer > Signed-off-by: Philippe Mathieu-Daudé <f4...@amsat.org> > --- > v2: Removed Red Hat authorship ¯\_(ツ)_/¯ > > hw/i386/vmport.c | 16 +++++++++++++++- > 1 file changed, 15 insertions(+), 1 deletion(-) > > diff --git a/hw/i386/vmport.c b/hw/i386/vmport.c > index 1aaaab691a..4ec95f8778 100644 > --- a/hw/i386/vmport.c > +++ b/hw/i386/vmport.c > @@ -24,6 +24,7 @@ > #include "qemu/osdep.h" > #include "hw/isa/isa.h" > #include "sysemu/hw_accel.h" > +#include "sysemu/qtest.h" > #include "qemu/log.h" > #include "vmport.h" > #include "cpu.h" > @@ -64,10 +65,14 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr > addr, > VMPortState *s = opaque; > CPUState *cs = current_cpu; > X86CPU *cpu = X86_CPU(cs); > - CPUX86State *env = &cpu->env; > + CPUX86State *env; > unsigned char command; > uint32_t eax; > > + if (qtest_enabled()) { > + return -1; > + } > + env = &cpu->env; > cpu_synchronize_state(cs); > > eax = env->regs[R_EAX]; > @@ -90,6 +95,9 @@ static void vmport_ioport_write(void *opaque, hwaddr addr, > { > X86CPU *cpu = X86_CPU(current_cpu); > > + if (qtest_enabled()) { > + return; > + } > cpu->env.regs[R_EAX] = vmport_ioport_read(opaque, addr, 4); > } > > @@ -97,6 +105,9 @@ static uint32_t vmport_cmd_get_version(void *opaque, > uint32_t addr) > { > X86CPU *cpu = X86_CPU(current_cpu); > > + if (qtest_enabled()) { > + return -1; > + } > cpu->env.regs[R_EBX] = VMPORT_MAGIC; > return 6; > } > @@ -105,6 +116,9 @@ static uint32_t vmport_cmd_ram_size(void *opaque, > uint32_t addr) > { > X86CPU *cpu = X86_CPU(current_cpu); > > + if (qtest_enabled()) { > + return -1; > + } > cpu->env.regs[R_EBX] = 0x1177; > return ram_size; > } >
Queued, thanks. Paolo