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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/libxls/libxls/issues/124
## Description:
Issue: libxls/libxls#124
Title: There are multiple heap-buffer-overflow vulnerability found in libxls
State: closed
Created by: mondaylord
Created at: 2023-07-13 06:31:34+00:00

Issue Body:
Hi, developers of libxls:
In the test of the binary `test2_libxls` instrumented with ASAN. There are 6 heap-buffer-overflow and 1 SEGV vulnerabilities in 
 `src/xls.c:1015`, `src/xls.c:1018`, `src/xlstool.c:266`, `src/xlstool.c:411`, `src/xlstool.c:395`, and `src/xlstool.c:296`. Here is the ASAN mode output (I omit some unnecessary messages):

### Vulnerability 1, src/xls.c:1015

=================================================================
==54038==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000001070 at pc 0x0000004cf305 bp 0x7fff55151350 sp 0x7fff55151348
READ of size 2 at 0x602000001070 thread T0
    #0 0x4cf304 in xls_parseWorkBook /libxls/src/xls.c:1015:37
    #1 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14
    #2 0x4c5b4d in main /libxls/test/test2.c:60:9
    #3 0x7f7fd826bc86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #4 0x41c109 in _start (/libxls/test2_libxls+0x41c109)

0x602000001071 is located 0 bytes to the right of 1-byte region [0x602000001070,0x602000001071)
allocated by thread T0 here:
    #0 0x4960f9 in realloc (/libxls/test2_libxls+0x4960f9)
    #1 0x4cb76a in xls_parseWorkBook /libxls/src/xls.c:860:24
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14

SUMMARY: AddressSanitizer: heap-buffer-overflow /libxls/src/xls.c:1015:37 in xls_parseWorkBook
Shadow bytes around the buggy address:
  0x0c047fff81b0: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa
  0x0c047fff81c0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fd
  0x0c047fff81d0: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c047fff81e0: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x0c047fff81f0: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fd
=>0x0c047fff8200: fa fa fd fd fa fa fd fd fa fa fd fa fa fa[01]fa
  0x0c047fff8210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8250: 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
==54038==ABORTING


### Vulnerability 2,  src/xls.c:1018

=================================================================
==24506==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000533 at pc 0x0000004ceb06 bp 0x7fffbc197e90 sp 0x7fffbc197e88
READ of size 1 at 0x602000000533 thread T0
    #0 0x4ceb05 in xls_parseWorkBook /libxls/src/xls.c:1018:38
    #1 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14
    #2 0x4c5b4d in main /libxls/test/test2.c:60:9
    #3 0x7ffb26d5bc86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #4 0x41c109 in _start (/libxls/test2_libxls+0x41c109)

0x602000000533 is located 0 bytes to the right of 3-byte region [0x602000000530,0x602000000533)
allocated by thread T0 here:
    #0 0x4960f9 in realloc (/libxls/test2_libxls+0x4960f9)
    #1 0x4cb76a in xls_parseWorkBook /libxls/src/xls.c:860:24
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14

SUMMARY: AddressSanitizer: heap-buffer-overflow /libxls/src/xls.c:1018:38 in xls_parseWorkBook


### Vulnerability 3, src/xlstool.c:266

=================================================================
==22361==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000954 at pc 0x0000004c6ec4 bp 0x7ffd36438770 sp 0x7ffd36438768
READ of size 1 at 0x603000000954 thread T0
    #0 0x4c6ec3 in unicode_decode_wcstombs /libxls/src/xlstool.c:266:38
    #1 0x4cc9a1 in xls_parseWorkBook /libxls/src/xls.c:1020:16
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14
    #3 0x4c5b4d in main /libxls/test/test2.c:60:9
    #4 0x7f0ca9da0c86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #5 0x41c109 in _start (/libxls/test2_libxls+0x41c109)

0x603000000954 is located 0 bytes to the right of 20-byte region [0x603000000940,0x603000000954)
allocated by thread T0 here:
    #0 0x4960f9 in realloc (/libxls/test2_libxls+0x4960f9)
    #1 0x4cb76a in xls_parseWorkBook /libxls/src/xls.c:860:24
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14

SUMMARY: AddressSanitizer: heap-buffer-overflow /libxls/src/xlstool.c:266:38 in unicode_decode_wcstombs


### Vulnerability 4, src/xlstool.c:411

=================================================================
==27366==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000514 at pc 0x0000004c7363 bp 0x7ffc82ab3a00 sp 0x7ffc82ab39f8
READ of size 1 at 0x602000000514 thread T0
    #0 0x4c7362 in get_string /libxls/src/xlstool.c:411:8
    #1 0x4cc9a1 in xls_parseWorkBook /libxls/src/xls.c:1020:16
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14
    #3 0x4c5b4d in main /libxls/test/test2.c:60:9
    #4 0x7fd80a51ac86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #5 0x41c109 in _start (/libxls/test2_libxls+0x41c109)

0x602000000514 is located 0 bytes to the right of 4-byte region [0x602000000510,0x602000000514)
allocated by thread T0 here:
    #0 0x4960f9 in realloc (/libxls/test2_libxls+0x4960f9)
    #1 0x4cb76a in xls_parseWorkBook /libxls/src/xls.c:860:24
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14

SUMMARY: AddressSanitizer: heap-buffer-overflow /libxls/src/xlstool.c:411:8 in get_string


### Vulnerability 5, src/xlstool.c:296

=================================================================
==19616==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x616000000888 at pc 0x0000004c6a11 bp 0x7fff62de6cc0 sp 0x7fff62de6cb8
READ of size 4 at 0x616000000888 thread T0
    #0 0x4c6a10 in transcode_latin1_to_utf8 /libxls/src/xlstool.c:296:12
    #1 0x4c6a10 in codepage_decode /src/xlstool.c:321:16
    #2 0x4cc9a1 in xls_parseWorkBook /libxls/src/xls.c:1020:16
    #3 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14
    #4 0x4c5b4d in main /libxls/test/test2.c:60:9
    #5 0x7f8d9df3ac86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #6 0x41c109 in _start (/libxls/test2_libxls+0x41c109)

0x616000000888 is located 0 bytes to the right of 520-byte region [0x616000000680,0x616000000888)
allocated by thread T0 here:
    #0 0x4960f9 in realloc (/libxls/test2_libxls+0x4960f9)
    #1 0x4cb76a in xls_parseWorkBook /libxls/src/xls.c:860:24
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14

SUMMARY: AddressSanitizer: heap-buffer-overflow /libxls/src/xlstool.c:296:12 in transcode_latin1_to_utf8


### Vulnerability 6, src/xlstool.c:395

=================================================================
==43284==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000005d2 at pc 0x0000004c7329 bp 0x7fffc6505260 sp 0x7fffc6505258
READ of size 1 at 0x6020000005d2 thread T0
    #0 0x4c7328 in get_string /libxls/src/xlstool.c:395:13
    #1 0x4cc9a1 in xls_parseWorkBook /libxls/src/xls.c:1020:16
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14
    #3 0x4c5b4d in main /libxls/test/test2.c:60:9
    #4 0x7fa1da3bcc86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #5 0x41c109 in _start (/libxls/test2_libxls+0x41c109)

0x6020000005d2 is located 0 bytes to the right of 2-byte region [0x6020000005d0,0x6020000005d2)
allocated by thread T0 here:
    #0 0x4960f9 in realloc (/libxls/test2_libxls+0x4960f9)
    #1 0x4cb76a in xls_parseWorkBook /libxls/src/xls.c:860:24
    #2 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14

SUMMARY: AddressSanitizer: heap-buffer-overflow /libxls/src/xlstool.c:395:13 in get_string


### Vulnerability 7

=================================================================
==38465==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000004cc923 bp 0x7ffee6e50330 sp 0x7ffee6e501a0 T0)
==38465==The signal is caused by a READ memory access.
==38465==Hint: address points to the zero page.
    #0 0x4cc923 in xls_parseWorkBook /libxls/src/xls.c:1015:41
    #1 0x4d7ee5 in xls_open_ole /libxls/src/xls.c:1480:14
    #2 0x4c5b4d in main /libxls/test/test2.c:60:9
    #3 0x7f032a36dc86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #4 0x41c109 in _start (/libxls/test2_libxls+0x41c109)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /libxls/src/xls.c:1015:41 in xls_parseWorkBook
==38465==ABORTING

### Crash input
https://github.com/17ssDP/fuzzer_crashes/tree/main/libxls

### Code Location
`xls.c:1010-1025`
```
case XLS_RECORD_STYLE:
			if(xls_debug) {
				struct { unsigned short idx; unsigned char ident; unsigned char lvl; } *styl;
				styl = (void *)buf;

				printf("    idx: 0x%x\n", styl->idx & 0x07FF); <----------
				if(styl->idx & 0x8000) {
					printf("  ident: 0x%x\n", styl->ident);
					printf("  level: 0x%x\n", styl->lvl); <---------
				} else {
					char *s = get_string((char *)&buf[2], bof1.size - 2, 1, pWB);
					printf("  name=%s\n", s);
                    free(s);
				}
			}
			break;
```

`xlstool.c:264-267`
```
for(i=0; i<len/2; i++)
    {
        w[i] = (BYTE)s[2*i] + ((BYTE)s[2*i+1] << 8); <----------
    }

```

`xlstool.c:406-413`
```
if(!pWB->is5ver) {
		// unicode strings have a format byte before the string
        if (ofs + 1 > len) {
            return NULL;
        }
		flag=*(BYTE*)(str+ofs); <-----------
		ofs++;
	}
```


`xlstool.c:392-296`
```
if (ofs + 2 > len) {
            return NULL;
        }
        ln= ((BYTE*)str)[0] + (((BYTE*)str)[1] << 8); <------------
        ofs+=2;

```

`xlstool.c:295-299`
```
for(i=0; i<len; ++i) {
        if(str[i] & (BYTE)0x80) { <-------------
            ++utf8_chars;
        }
    }

```
### Environment
Ubuntu 16.04
Clang 10.0.1
gcc 5.5


Build script:
# Minimized build script with only core build commands
set -eu
./bootstrap
./configure --enable-static
make clean -j$(nproc)
make -j$(nproc)
make fuzz_xls -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make autoconf autoconf-archive automake gettext libtool
RUN git clone https://github.com/libxls/libxls libxls
RUN git -C libxls checkout 448240067919707eb95fb009f76f3fdb439b1427
WORKDIR $SRC/libxls
COPY build.sh $SRC/

Additional files: