On 5/23/20 8:03 PM, Philippe Mathieu-Daudé wrote: > Public bug reported: > > As of commit d19f1ab0, LLVM libFuzzer found: > > ================================================================= > ==6814==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fd89f97bd5a at pc 0x55dc44594db5 bp 0x7ffd6f461b40 sp 0x7ffd6f461b38 > READ of size 1 at 0x7fd89f97bd5a thread T0 > #0 0x55dc44594db4 in artist_rop8 > #1 0x55dc44595fd9 in draw_line > #2 0x55dc445937e4 in draw_line_size > #3 0x55dc4458ee9d in artist_reg_write > #4 0x55dc43f77ba7 in memory_region_write_accessor > #5 0x55dc43f775b8 in access_with_adjusted_size > #6 0x55dc43f762b3 in memory_region_dispatch_write > #7 0x55dc43dbb322 in flatview_write_continue > #8 0x55dc43dab2e2 in flatview_write > #9 0x55dc43daae14 in address_space_write > > 0x7fd89f97bd5a is located 1122 bytes to the right of 16777464-byte region [0x7fd89e97b800,0x7fd89f97b8f8) > allocated by thread T0 here: > #0 0x55dc43d87abf in operator new(unsigned long) > #1 0x55dc43c4274d in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) > #2 0x55dc43c3a526 in main (qemu-fuzz-hppa+0x982526) > #3 0x7fd8d05edf42 in __libc_start_main (/lib64/libc.so.6+0x23f42) > > SUMMARY: AddressSanitizer: heap-buffer-overflow (qemu-fuzz-hppa+0x12dcdb4) in artist_rop8 > Shadow bytes around the buggy address: > 0x0ffb93f27750: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f27760: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f27770: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f27780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f27790: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > =>0x0ffb93f277a0: fa fa fa fa fa fa fa fa fa fa fa[fa]fa fa fa fa > 0x0ffb93f277b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f277c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f277d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f277e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > 0x0ffb93f277f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > Shadow byte legend (one shadow byte represents 8 application bytes): > Addressable: 00 > Partially addressable: 01 02 03 04 05 06 07 > Heap left redzone: fa > Freed heap region: fd > Stack left redzone: f1 > Stack mid redzone: f2 > Stack right redzone: f3 > Stack after return: f5 > Stack use after scope: f8 > Global redzone: f9 > Global init order: f6 > Poisoned by user: f7 > Container overflow: fc > Array cookie: ac > Intra object redzone: bb > ASan internal: fe > Left alloca redzone: ca > Right alloca redzone: cb > Shadow gap: cc > ==6814==ABORTING > > How to reproduce: > > qemu-system-hppa -S -qtest stdio -accel qtest -display none < EOF > writeb 0xf8100081 0x40 > writeb 0xf81000c5 0x40 > writeb 0xf8100e44 0x2b > writeb 0xf8100e44 0x56 > writeb 0xf8100e44 0x10 > writeb 0xf8100600 0x0 > writeb 0xf8100821 0x21 > writeb 0xf8100b01 0x14 > writew 0xf8100044 0x1245 > writeb 0xf8100a0e 0x50 > writeb 0xf8100a02 0x49 > writeb 0xf8100821 0x0 > writew 0xf8100014 0x0 > writeb 0xf8100e46 0x46 > writeb 0xf8100052 0xe > writeb 0xf8100621 0x14 > writeb 0xf8100b01 0x14 > writew 0xf8100044 0x1241 > writeb 0xf8100b02 0x25 > writeb 0xf8100b01 0x4 > writeb 0xf8100e46 0xb0 > writeb 0xf8100b02 0x0 > writel 0xf81000c4 0x49494949 > writeb 0xf8100b02 0x10 > writew 0xf8100010 0x11 > writew 0xf8100044 0x1212 > writew 0xf8100044 0x1245 > writew 0xf8100050 0xe2a > writeb 0xf8100002 0x11 > writeb 0xf8100081 0xec > writeb 0xf8100081 0xec > writeb 0xf810030e 0xe > writeb 0xf810000e 0x44 > writeb 0xf8100000 0xe > writeb 0xf8100044 0xe > writeb 0xf8100000 0xe > writeb 0xf810030e 0x13 > writeb 0xf8100b44 0x2a > writeb 0xf8100bf8 0x4 > writeb 0xf8100007 0x45 > writeb 0xf81000ff 0xff > writew 0xf8100044 0xf042 > writew 0xf8100000 0x45 > writew 0xf8100044 0xf042 > writeb 0xf8100000 0xc5 > writeb 0xf81000ff 0xff > writel 0xf8100044 0x101364ff > writel 0xf81000c4 0xfba0a0a0 > writeb 0xf8100000 0x2a > writeb 0xf81000c5 0x40 > writeb 0xf81000ff 0xdf > writew 0xf8100000 0x4144 > writeb 0xf81000df 0x0 > writew 0xf8100044 0x4400 > writel 0xf8100044 0x101364ff > writel 0xf81000c4 0xfb490045 > writeb 0xf8100000 0x2a > writeb 0xf81000c5 0x40 > writel 0xf8100044 0x101364ff > writel 0xf8100bc4 0x49004545 > writeb 0xf8100000 0x2a > writeb 0xf81000c5 0x40 > writeb 0xf810000e 0x21 > writeb 0xf8100000 0x2a > writeb 0xf81000c3 0x40 > writeb 0xf81000ff 0xdf > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100000 0x4144 > writew 0xf8100044 0x4400 > writew 0xf8100000 0x4144 > writew 0xf81000bc 0xc100 > writew 0xf8100000 0x4144 > writew 0xf81000bc 0xc100 > writew 0xf8100044 0x1210 > writel 0xf8100044 0xfb53000a > writew 0xf8100044 0x1210 > writel 0xf8100044 0xfb53000a > writew 0xf8100044 0x1210 > writel 0xf8100044 0xfba7000a > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100000 0x4144 > writew 0xf8100000 0x4144 > writew 0xf8100000 0x4144 > writew 0xf8100044 0x4400 > writew 0xf8100044 0x4411 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1212 > writew 0xf8100044 0x4445 > writeb 0xf81000ff 0xff > writeb 0xf8100121 0x14 > writeb 0xf8100121 0x14 > writeb 0xf8100421 0x0 > writeb 0xf8100421 0x28 > writeb 0xf8100000 0x2a > writeb 0xf81000c5 0x40 > writeb 0xf8100040 0x0 > writeb 0xf8100007 0x45 > writeb 0xf8100007 0x45 > writeb 0xf8100bf8 0x4 > writeb 0xf8100bf8 0x4 > writeb 0xf8100bf8 0x4 > writeb 0xf8100bf8 0x4 > writeb 0xf8100bf8 0x4 > writew 0xf8100060 0x11 > writew 0xf8100060 0x11 > writew 0xf8100060 0x17 > writeb 0xf8100446 0x46 > writeb 0xf8100604 0x50 > writeb 0xf8100821 0x21 > writeb 0xf8100108 0x21 > writeb 0xf810010c 0x21 > writeb 0xf8100081 0xec > writeb 0xf8100041 0xec > writel 0xf8100044 0x101364ff > writel 0xf81000c4 0xfba0a0a0 > writel 0xf8100044 0x101364ff > writel 0xf81000c4 0xfba0a0a0 > writel 0xf8100044 0x101364ff > writel 0xf81000c4 0xfba0a0a0 > writeb 0xf8100052 0x24 > writew 0xf8100000 0x4144 > writeb 0xf81000df 0x0 > writew 0xf8100044 0x4400 > writew 0xf8100000 0x4144 > writeb 0xf81000df 0x41 > writeb 0xf8100504 0x50 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100094 0x4145 > writel 0xf8100044 0x10424410 > writel 0xf81000a0 0xa0a0492a > writel 0xf8100044 0x10040000 > writeb 0xf8100007 0x44 > writeb 0xf81000ff 0xff > writeb 0xf8100007 0x44 > writeb 0xf81000ff 0x4 > writel 0xf8100044 0x10134900 > writeb 0xf8100000 0x2a > writeb 0xf81000c5 0x40 > writeb 0xf8100000 0x2a > writeb 0xf81000c5 0x40 > writew 0xf8100040 0x1212 > writew 0xf8100044 0x1245 > writew 0xf8100040 0x1212 > writew 0xf8100040 0x5002 > writew 0xf8100040 0x5002 > writew 0xf8100040 0x502a > writeb 0xf8100081 0x40 > writeb 0xf810005d 0x40 > writeb 0xf8100030 0x5d > writeb 0xf8100e44 0x44 > writeb 0xf8100044 0x3 > writeb 0xf8100044 0x3 > writeb 0xf8100044 0x13 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1210 > writew 0xf8100044 0x6d10 > writeb 0xf8100044 0x6d > writeb 0xf8100000 0x2a > writeb 0xf8100044 0x40 > writeb 0xf8100045 0xec > writew 0xf8100044 0x1210 > writew 0xf8100044 0x1245 > writel 0xf8100044 0x101364ff > writel 0xf81000c4 0xfba0a0a0 > writel 0xf8100044 0x101364ff > writel 0xf8100044 0x101364ff > writel 0xf8100044 0x101364ff > writel 0xf8100008 0xfba0a0a0 > writel 0xf8100044 0x4208fba0 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100000 0x4144 > writeb 0xf810030e 0xe > writeb 0xf810030e 0xe > writeb 0xf810032b 0xe > writeb 0xf810032b 0xe > writew 0xf8100010 0x4412 > writew 0xf81000ca 0x4441 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writeb 0xf8100080 0xe > writeb 0xf8100080 0xd8 > writeb 0xf8100080 0x26 > writeb 0xf8100040 0x80 > writeb 0xf8100040 0x26 > writeb 0xf81000c3 0x40 > writeb 0xf81000ff 0xdf > writeb 0xf81000c3 0x40 > writeb 0xf81000ff 0xdf > writew 0xf8100014 0x4000 > writeb 0xf8100000 0xe > writeb 0xf8100000 0x9e > writeb 0xf8100000 0x3c > writeb 0xf8100000 0x3c > writeb 0xf8100000 0x3c > writew 0xf8100000 0x4144 > writeb 0xf81000df 0x41 > writeb 0xf8100007 0x45 > writeb 0xf81000ff 0xff > writeb 0xf8100007 0xb4 > writeb 0xf81000ff 0xff > writeb 0xf8100007 0xb4 > writeb 0xf8100007 0xb4 > writel 0xf8100044 0x10139c05 > writel 0xf81000c4 0xfba0a0a0 > writeb 0xf8100604 0x50 > writeb 0xf8100021 0xe > writeb 0xf8100021 0xe > writeb 0xf8100021 0xe > writeb 0xf8100021 0x90 > writew 0xf8100010 0x11 > writew 0xf8100010 0x11 > writew 0xf8100010 0x11 > writeb 0xf8100021 0xe > writeb 0xf8100021 0xe > writeb 0xf8100021 0xe > writeb 0xf8100021 0xe > writeb 0xf8100021 0xe > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writew 0xf8100010 0x4412 > writeb 0xf8100021 0xe > writeb 0xf8100021 0xe > writeb 0xf8100021 0x21 > writeb 0xf8100021 0x21 > writeb 0xf8100000 0x0 > writeb 0xf8100e04 0x46 > EOF > > Program terminated with signal SIGSEGV, Segmentation fault. > #0 0x000056367b2085c0 in artist_rop8 (s=0x56367d38b510, dst=0x7f9f972fffff , val=0 '\000') at hw/display/artist.c:284 > 284 *dst &= ~plane_mask; > (gdb) bt > #0 0x000056367b2085c0 in artist_rop8 (s=0x56367d38b510, dst=0x7f9f972fffff , val=0 '\000') at hw/display/artist.c:284 > #1 0x000056367b209325 in draw_line (s=0x56367d38b510, x1=-20480, y1=-1, x2=0, y2=17920, update_start=true, skip_pix=-1, max_pix=-1) at hw/display/artist.c:646 > #2 0x000056367b2095a0 in draw_line_size (s=0x56367d38b510, update_start=true) at hw/display/artist.c:696 > #3 0x000056367b20a214 in artist_reg_write (opaque=0x56367d38b510, addr=1052164, val=70, size=1) at hw/display/artist.c:932 > #4 0x000056367b06ea7c in memory_region_write_accessor (mr=0x56367d38ba10, addr=1052164, value=0x7fff112132d8, size=1, shift=0, mask=255, attrs=...) at memory.c:483 > #5 0x000056367b06ec33 in access_with_adjusted_size (addr=1052164, value=0x7fff112132d8, size=1, access_size_min=1, access_size_max=4, access_fn= > 0x56367b06e999 , mr=0x56367d38ba10, attrs=...) at memory.c:540 > #6 0x000056367b071bb4 in memory_region_dispatch_write (mr=0x56367d38ba10, addr=1052164, data=70, op=MO_8, attrs=...) at memory.c:1477 > #7 0x000056367b00fe33 in flatview_write_continue (fv=0x56367d6f9fa0, addr=4161801732, attrs=..., ptr=0x7fff112134e0, len=1, addr1=1052164, l=1, mr=0x56367d38ba10) at exec.c:3147 > #8 0x000056367b00ff81 in flatview_write (fv=0x56367d6f9fa0, addr=4161801732, attrs=..., buf=0x7fff112134e0, len=1) at exec.c:3190 > #9 0x000056367b0102eb in address_space_write (as=0x56367cff99c0, addr=4161801732, attrs=..., buf=0x7fff112134e0, len=1) at exec.c:3289 > > ** Affects: qemu > Importance: Undecided > Status: New > The crash is avoided using this patch: -- >8 -- diff --git a/hw/display/artist.c b/hw/display/artist.c index 6e17c43f13..fcfd67da47 100644 --- a/hw/display/artist.c +++ b/hw/display/artist.c @@ -563,7 +563,7 @@ static void fill_window(ARTISTState *s, int startx, int starty, static void draw_line(ARTISTState *s, int x1, int y1, int x2, int y2, bool update_start, int skip_pix, int max_pix) { - struct vram_buffer *buf; + struct vram_buffer *buf = &s->vram_buffer[ARTIST_BUFFER_AP]; uint8_t color; int dx, dy, t, e, x, y, incy, diago, horiz; bool c1; @@ -571,6 +571,12 @@ static void draw_line(ARTISTState *s, int x1, int y1, int x2, int y2, trace_artist_draw_line(x1, y1, x2, y2); + if (x1 * y1 >= buf->size || x2 * y2 >= buf->size) { + qemu_log_mask(LOG_GUEST_ERROR, + "draw line (%d,%d) (%d,%d)\n", x1, y1, x2, y2); + return; + } + if (update_start) { s->vram_start = (x2 << 16) | y2; } @@ -628,7 +634,6 @@ static void draw_line(ARTISTState *s, int x1, int y1, int x2, int y2, x = x1; y = y1; color = artist_get_color(s); - buf = &s->vram_buffer[ARTIST_BUFFER_AP]; do { if (c1) { --- I am not sure this is the best fix, IMO the invalid value should be reported earlier.