Project: libredwg (libredwg/libredwg), language: c++
Vulnerability instance: libredwg.cve-2023-36271
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/LibreDWG/libredwg/issues/681#BUG2
## Description:
Issue: LibreDWG/libredwg#681
Title: [FUZZ] two bugs in dwg2SVG
State: closed
Created by: kdsjZh
Created at: 2023-03-31 04:10:48+00:00

Issue Body:
Hello, I was testing my fuzzer and found two bugs in dwg2SVG.

## environment
ubuntu 20.04, GCC 9.4.0, libredwg latest commit 9df4ec3c524795a401acf371c8a953f5b1a6fadf

compile with

```
./autogen.sh && ./configure --disable-shared && make -j$(nproc)
```

##BUG1
```
./dwg2SVG ../pocs/poc0.bit_utf8_to_TU
=================================================================
==19712==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000dc at pc 0x5603ca37f05a bp 0x7fff049b1c90 sp 0x7fff049b1c80
WRITE of size 2 at 0x6020000000dc thread T0
    #0 0x5603ca37f059 in bit_utf8_to_TU /libredwg/src/bits.c:2883
    #1 0x5603cae6faab in dwg_is_valid_tag /libredwg/src/dwg_api.c:22059
    #2 0x5603cae6faab in dwg_is_valid_tag /libredwg/src/dwg_api.c:22048
    #3 0x5603ca7744de in dwg_decode_ATTRIB_private /libredwg/src/dwg.spec:204
    #4 0x5603ca8fe1ec in dwg_decode_ATTRIB /libredwg/src/dwg.spec:187
    #5 0x5603cacaa3a2 in decode_preR13_entities /libredwg/src/decode.c:6520
    #6 0x5603cacf559c in decode_preR13 /libredwg/src/decode_r11.c:719
    #7 0x5603cac76a6a in dwg_decode /libredwg/src/decode.c:217
    #8 0x5603ca362d77 in dwg_read_file /libredwg/src/dwg.c:261
    #9 0x5603ca35857c in main /libredwg/programs/dwg2SVG.c:979
    #10 0x7fc02854f082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
    #11 0x5603ca358c1d in _start (/validate/dwg2SVG/dwg2SVG+0x206c1d)

0x6020000000dc is located 0 bytes to the right of 12-byte region [0x6020000000d0,0x6020000000dc)
allocated by thread T0 here:
    #0 0x7fc028979a06 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x5603ca37e83a in bit_utf8_to_TU /libredwg/src/bits.c:2856

SUMMARY: AddressSanitizer: heap-buffer-overflow /libredwg/src/bits.c:2883 in bit_utf8_to_TU
Shadow bytes around the buggy address:
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff8000: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa 00 00
=>0x0c047fff8010: fa fa 02 fa fa fa 01 fa fa fa 00[04]fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8060: 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
==19712==ABORTING
```

##BUG2

```
./dwg2SVG ../pocs/poc1.bit_wcs2nlen
==19713==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000097a at pc 0x55781f6dd09d bp 0x7ffc201cb2e0 sp 0x7ffc201cb2d0
READ of size 2 at 0x60400000097a thread T0
    #0 0x55781f6dd09c in bit_wcs2nlen /libredwg/src/bits.c:1834
    #1 0x5578201d2abb in dwg_is_valid_tag /libredwg/src/dwg_api.c:22060
    #2 0x5578201d2abb in dwg_is_valid_tag /libredwg/src/dwg_api.c:22048
    #3 0x55781fad74de in dwg_decode_ATTRIB_private /libredwg/src/dwg.spec:204
    #4 0x55781fc611ec in dwg_decode_ATTRIB /libredwg/src/dwg.spec:187
    #5 0x55782000d3a2 in decode_preR13_entities /libredwg/src/decode.c:6520
    #6 0x55782005859c in decode_preR13 /libredwg/src/decode_r11.c:719
    #7 0x55781ffd9a6a in dwg_decode /libredwg/src/decode.c:217
    #8 0x55781f6c5d77 in dwg_read_file /libredwg/src/dwg.c:261
    #9 0x55781f6bb57c in main /libredwg/programs/dwg2SVG.c:979
    #10 0x7faa3dcaf082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
    #11 0x55781f6bbc1d in _start (/validate/dwg2SVG/dwg2SVG+0x206c1d)

0x60400000097a is located 0 bytes to the right of 42-byte region [0x604000000950,0x60400000097a)
allocated by thread T0 here:
    #0 0x7faa3e0d9a06 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:153
    #1 0x55781f6e183a in bit_utf8_to_TU /libredwg/src/bits.c:2856

SUMMARY: AddressSanitizer: heap-buffer-overflow /libredwg/src/bits.c:1834 in bit_wcs2nlen
Shadow bytes around the buggy address:
  0x0c087fff80d0: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00
  0x0c087fff80e0: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00
  0x0c087fff80f0: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00
  0x0c087fff8100: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 fa
  0x0c087fff8110: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00
=>0x0c087fff8120: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00[02]
  0x0c087fff8130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8160: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff8170: 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
==19713==ABORTING
```

## POC

[poc.zip](https://github.com/LibreDWG/libredwg/files/11118078/poc.zip)

## Credit
Han Zheng (Hexhive, NCNIPC of China)



Comments:
Comment by kdsjZh on 2023-03-31 04:23:57+00:00:
Besides, I also find the patch for #677 BUG1 might be incomplete and I attach an additional poc for the latest version. pls check it out if you have time. Thanks for your efforts and quick fix in advance!

---

Comment by rurban on 2023-03-31 04:32:14+00:00:
Good fuzzer, hexhive! 

---

Comment by rurban on 2023-03-31 06:07:45+00:00:
Both are decode only, thus dwgread would be enough

Attachments:
https://github.com/LibreDWG/libredwg/files/11118078/poc.zip

Commit References:
9df4ec3c524795a401acf371c8a953f5b1a6fadf

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
sh ./autogen.sh
./configure --disable-shared --disable-bindings --enable-release
make -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y autoconf libtool texinfo
RUN git clone https://github.com/libredwg/libredwg libredwg
RUN git -C libredwg checkout 24cea42a1a2e96d2a6028a4d9f9ea1e7574af77f
WORKDIR $SRC/libredwg
COPY build.sh $SRC/

Additional files:
filename: llvmfuzz.options
content: [libfuzzer]
detect_leaks=0