Project: libiec61850 (mz-automation/libiec61850), language: c++
Vulnerability instance: libiec61850.cve-2019-19958
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/mz-automation/libiec61850/issues/198
## Description:
Issue: mz-automation/libiec61850#198
Title: integer signedness in StringUtils_createStringFromBuffer in src/common/string_utilities.c
State: closed
Created by: sleicasper
Created at: 2019-12-24 09:08:24+00:00

Issue Body:
`StringUtils_createStringFromBuffer`'s second argument is `size` which is a signed integer. If attacker supply a negtive number like -1, `StringUtils_createStringFromBuffer` will try to alloc a very large buffer that is size 0xffffffff in 32bit arch or 0xffffffffffffffff in 64 bit arch. Most of the time alloc will failed then `memcpy` will get segment fault.

<img width="594" alt="Screen Shot 2019-12-24 at 5 00 57 PM" src="https://user-images.githubusercontent.com/20929895/71405272-eb5a2400-266f-11ea-8f27-16df7337247f.png">


poc:
[poc.zip](https://github.com/mz-automation/libiec61850/files/3997788/poc.zip)


gdb results:
```
gdb-peda$ r < /tmp/poc
Starting program: /home/casper/targets/struct/libiec61850/afl/fuzzrun/fuzzmmsdata < /tmp/poc
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
=================================================================
==1860==ERROR: AddressSanitizer: negative-size-param: (size=-1)
    #0 0x491fd7  (/home/casper/targets/struct/libiec61850/afl/fuzzrun/fuzzmmsdata+0x491fd7)
    #1 0x7ffff7839090  (/home/casper/targets/struct/libiec61850/afl/INSTALL/lib/libiec61850.so.1.4.0+0x49090)
    #2 0x7ffff787d08c  (/home/casper/targets/struct/libiec61850/afl/INSTALL/lib/libiec61850.so.1.4.0+0x8d08c)
    #3 0x7ffff7913d3b  (/home/casper/targets/struct/libiec61850/afl/INSTALL/lib/libiec61850.so.1.4.0+0x123d3b)
    #4 0x4c2377  (/home/casper/targets/struct/libiec61850/afl/fuzzrun/fuzzmmsdata+0x4c2377)
    #5 0x7ffff683fb96  (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #6 0x41acf9  (/home/casper/targets/struct/libiec61850/afl/fuzzrun/fuzzmmsdata+0x41acf9)

Address 0x000000f9892f is a wild pointer.
SUMMARY: AddressSanitizer: negative-size-param (/home/casper/targets/struct/libiec61850/afl/fuzzrun/fuzzmmsdata+0x491fd7)
==1860==ABORTING

Program received signal SIGABRT, Aborted.
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x705a28 --> 0x0
RCX: 0x7ffff685ce97 (<__GI_raise+199>:	mov    rcx,QWORD PTR [rsp+0x108])
RDX: 0x0
RSI: 0x7fffffffc9b0 --> 0x0
RDI: 0x2
RBP: 0x7fffffffe140 --> 0xffffffff --> 0x0
RSP: 0x7fffffffc9b0 --> 0x0
RIP: 0x7ffff685ce97 (<__GI_raise+199>:	mov    rcx,QWORD PTR [rsp+0x108])
R8 : 0x0
R9 : 0x7fffffffc9b0 --> 0x0
R10: 0x8
R11: 0x246
R12: 0x7fffffffd908 --> 0x7fffffffd918 --> 0x491fd8 (<__asan_memcpy()+344>:	lea    rcx,[rip+0x305ea9]        # 0x797e88 <_ZN11__sanitizer21common_flags_dont_useE>)
R13: 0x2
R14: 0x7fffffffcd00 --> 0x7ffff6c101ba --> 0x8b000000000000
R15: 0x797e88 --> 0x1
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x7ffff685ce8b <__GI_raise+187>:	mov    edi,0x2
   0x7ffff685ce90 <__GI_raise+192>:	mov    eax,0xe
   0x7ffff685ce95 <__GI_raise+197>:	syscall
=> 0x7ffff685ce97 <__GI_raise+199>:	mov    rcx,QWORD PTR [rsp+0x108]
   0x7ffff685ce9f <__GI_raise+207>:	xor    rcx,QWORD PTR fs:0x28
   0x7ffff685cea8 <__GI_raise+216>:	mov    eax,r8d
   0x7ffff685ceab <__GI_raise+219>:	jne    0x7ffff685cecc <__GI_raise+252>
   0x7ffff685cead <__GI_raise+221>:	add    rsp,0x118
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffc9b0 --> 0x0
0008| 0x7fffffffc9b8 --> 0x0
0016| 0x7fffffffc9c0 --> 0x0
0024| 0x7fffffffc9c8 --> 0x0
0032| 0x7fffffffc9d0 --> 0x0
0040| 0x7fffffffc9d8 --> 0x0
0048| 0x7fffffffc9e0 --> 0x0
0056| 0x7fffffffc9e8 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGABRT
__GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:51
51	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
gdb-peda$ bt
#0  __GI_raise (sig=sig@entry=0x6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff685e801 in __GI_abort () at abort.c:79
#2  0x00000000004b06b7 in __sanitizer::Abort() () at /tmp/final/llvm.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc:154
#3  0x00000000004af091 in __sanitizer::Die() () at /tmp/final/llvm.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_termination.cc:58
#4  0x0000000000496c19 in ~ScopedInErrorReport () at /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_report.cc:186
#5  0x0000000000497e80 in ReportStringFunctionSizeOverflow () at /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_report.cc:340
#6  0x0000000000492013 in __asan_memcpy () at /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:22
#7  0x00007ffff7839091 in StringUtils_createStringFromBuffer (buf=0x7fffffffc9b0 "", size=<optimized out>) at /home/casper/targets/struct/libiec61850/afl/SRC/src/common/string_utilities.c:68
#8  0x00007ffff787d08d in MmsValue_newStringFromByteArray (byteArray=0xf9892f "", size=0xffffffff, type=MMS_VISIBLE_STRING) at /home/casper/targets/struct/libiec61850/afl/SRC/src/mms/iso_mms/common/mms_value.c:1725
#9  MmsValue_newVisibleStringFromByteArray (byteArray=0xf9892f "", size=0xffffffff) at /home/casper/targets/struct/libiec61850/afl/SRC/src/mms/iso_mms/common/mms_value.c:1739
#10 0x00007ffff7913d3c in MmsValue_decodeMmsData (buffer=<optimized out>, bufPos=0x0, bufferLength=<optimized out>, endBufPos=<optimized out>)
    at /home/casper/targets/struct/libiec61850/afl/SRC/src/mms/iso_mms/server/mms_access_result.c:277
#11 0x00000000004c2378 in main () at ../fuzzsrc/fuzzmmsdata.c:12
#12 0x00007ffff683fb97 in __libc_start_main (main=0x4c22e0 <main>, argc=0x1, argv=0x7fffffffe3c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe3b8) at ../csu/libc-start.c:310
#13 0x000000000041acfa in _start ()
```


Comments:
Comment by mzillgith on 2020-01-04 15:38:36+00:00:
Thanks for the bug report! Actually the caller has to provide valid arguments. The wrong value was caused by missing length validity checks in MmsValue_decodeMmsData. This is fixed with 6c53924.
I will also add a check if allocation fails in StringUtils_createStringFromBuffer

Attachments:
https://github.com/mz-automation/libiec61850/files/3997788/poc.zip

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
mkdir -p build && cd build
cmake ../
make -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN git clone https://github.com/mz-automation/libiec61850 libiec61850
RUN git -C libiec61850 checkout 6f7df75d85786b0e169ea007be959a51159a83cb
WORKDIR $SRC/libiec61850
COPY build.sh $SRC/

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