qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug 1880326] [NEW] memory writes make artist_rop8() crash


From: Philippe Mathieu-Daudé
Subject: Re: [Bug 1880326] [NEW] memory writes make artist_rop8() crash
Date: Sat, 23 May 2020 20:21:14 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0

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 
> <error: Cannot access memory at address 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 
> <error: Cannot access memory at address 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 <memory_region_write_accessor>, 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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]