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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/mz-automation/libiec61850/issues/164
## Description:
Issue: mz-automation/libiec61850#164
Title: Heap-use-after-free in server_example_goose
State: closed
Created by: c0d3xpl0it
Created at: 2019-09-09 18:14:27+00:00

Issue Body:
Hello we found Heap user after free vulnerability in server_example_goose binary.

**Below are steps followed to reproduce crash**
Download latest source code from : https://github.com/mz-automation/libiec61850.git and compiled using ASAN (cmake .. -DCMAKE_CXX_FLAGS="-fsanitize=address -fsanitize=leak -g -ggdb -fno-omit-frame-pointer -static-libstdc++ -static-libasan" -DCMAKE_C_FLAGS="-fsanitize=address -fsanitize=leak -g -ggdb -fno-omit-frame-pointer -static-libstdc++ -static-libasan")

**GDB Output**
```
fuzzer@fuzzer:~/libiec61850/build/examples/server_example_goose$ ifconfig
ens160    Link encap:Ethernet  HWaddr 00:0c:29:59:14:0c
          inet addr:10.1.56.103  Bcast:10.1.56.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe59:140c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2058541 errors:0 dropped:1800 overruns:0 frame:0
          TX packets:1996637 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:319927035 (319.9 MB)  TX bytes:947657776 (947.6 MB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:160 errors:0 dropped:0 overruns:0 frame:0
          TX packets:160 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:11840 (11.8 KB)  TX bytes:11840 (11.8 KB)


fuzzer@fuzzer:~/libiec61850/build/examples/server_example_goose$ gdb -q server_example_goose
Reading symbols from server_example_goose...done.
(gdb) run eth0
Starting program: /home/fuzzer/libiec61850/build/examples/server_example_goose/server_example_goose eth0
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Using GOOSE interface: eth0
[New Thread 0x7ffff49ff700 (LWP 14064)]
Starting server failed! Exit.
=================================================================
==14060==ERROR: AddressSanitizer: heap-use-after-free on address 0x61c00000f880 at pc 0x00000053c4c1 bp 0x7ffff49fee20 sp 0x7ffff49fee10
READ of size 8 at 0x61c00000f880 thread T1
    #0 0x53c4c0 in MmsServer_waitReady /home/fuzzer/libiec61850/src/mms/iso_mms/server/mms_server.c:482
    #1 0x4ebb57 in IedServer_waitReady /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:670
    #2 0x4eb606 in singleThreadedServerThread /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:568
    #3 0x5d5c3c in destroyAutomaticThread /home/fuzzer/libiec61850/hal/thread/linux/thread_linux.c:90
    #4 0x7ffff7bc16b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
    #5 0x7ffff71d441c in clone (/lib/x86_64-linux-gnu/libc.so.6+0x10741c)

0x61c00000f880 is located 0 bytes inside of 1760-byte region [0x61c00000f880,0x61c00000ff60)
freed by thread T0 here:
    #0 0x4a78fa in __interceptor_free (/home/fuzzer/libiec61850/build/examples/server_example_goose/server_example_goose+0x4a78fa)
    #1 0x5d662c in Memory_free /home/fuzzer/libiec61850/hal/memory/lib_memory.c:82
    #2 0x53bc0b in MmsServer_destroy /home/fuzzer/libiec61850/src/mms/iso_mms/server/mms_server.c:317
    #3 0x4eb250 in IedServer_destroy /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:506
    #4 0x4d7d81 in main /home/fuzzer/libiec61850/examples/server_example_goose/server_example_goose.c:82
    #5 0x7ffff70ed82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

previously allocated by thread T0 here:
    #0 0x4a7dca in calloc (/home/fuzzer/libiec61850/build/examples/server_example_goose/server_example_goose+0x4a7dca)
    #1 0x5d65c5 in Memory_calloc /home/fuzzer/libiec61850/hal/memory/lib_memory.c:59
    #2 0x53aada in MmsServer_create /home/fuzzer/libiec61850/src/mms/iso_mms/server/mms_server.c:53
    #3 0x4eabb4 in IedServer_createWithConfig /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:435
    #4 0x4eb193 in IedServer_create /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:484
    #5 0x4d7c5c in main /home/fuzzer/libiec61850/examples/server_example_goose/server_example_goose.c:56
    #6 0x7ffff70ed82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

Thread T1 created by T0 here:
    #0 0x4457c3 in pthread_create (/home/fuzzer/libiec61850/build/examples/server_example_goose/server_example_goose+0x4457c3)
    #1 0x5d5cc5 in Thread_start /home/fuzzer/libiec61850/hal/thread/linux/thread_linux.c:101
    #2 0x4eb79a in IedServer_start /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:597
    #3 0x4d7cda in main /home/fuzzer/libiec61850/examples/server_example_goose/server_example_goose.c:66
    #4 0x7ffff70ed82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-use-after-free /home/fuzzer/libiec61850/src/mms/iso_mms/server/mms_server.c:482 MmsServer_waitReady
Shadow bytes around the buggy address:
  0x0c387fff9ec0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c387fff9ed0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c387fff9ee0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c387fff9ef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c387fff9f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c387fff9f10:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c387fff9f20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c387fff9f30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c387fff9f40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c387fff9f50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c387fff9f60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==14060==ABORTING
[Thread 0x7ffff49ff700 (LWP 14064) exited]
[Inferior 1 (process 14060) exited with code 01]
(gdb) 
```

**ASAN Output**
```
fuzzer@fuzzer:~/libiec61850/build/examples/server_example_goose$ ./server_example_goose eth0
Using GOOSE interface: eth0
Starting server failed! Exit.
=================================================================
==14023==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000dfd0 at pc 0x0000004eb566 bp 0x7fd1531fee60 sp 0x7fd1531fee50
READ of size 8 at 0x60700000dfd0 thread T1
    #0 0x4eb565 in singleThreadedServerThread /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:556
    #1 0x5d5c3c in destroyAutomaticThread /home/fuzzer/libiec61850/hal/thread/linux/thread_linux.c:90
    #2 0x7fd1563b26b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
    #3 0x7fd1559c541c in clone (/lib/x86_64-linux-gnu/libc.so.6+0x10741c)

0x60700000dfd0 is located 32 bytes inside of 80-byte region [0x60700000dfb0,0x60700000e000)
freed by thread T0 here:
    #0 0x4a78fa in __interceptor_free (/home/fuzzer/libiec61850/build/examples/server_example_goose/server_example_goose+0x4a78fa)
    #1 0x5d662c in Memory_free /home/fuzzer/libiec61850/hal/memory/lib_memory.c:82
    #2 0x4eb497 in IedServer_destroy /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:534
    #3 0x4d7d81 in main /home/fuzzer/libiec61850/examples/server_example_goose/server_example_goose.c:82
    #4 0x7fd1558de82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

previously allocated by thread T0 here:
    #0 0x4a7dca in calloc (/home/fuzzer/libiec61850/build/examples/server_example_goose/server_example_goose+0x4a7dca)
    #1 0x5d65c5 in Memory_calloc /home/fuzzer/libiec61850/hal/memory/lib_memory.c:59
    #2 0x4ea824 in IedServer_createWithConfig /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:394
    #3 0x4eb193 in IedServer_create /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:484
    #4 0x4d7c5c in main /home/fuzzer/libiec61850/examples/server_example_goose/server_example_goose.c:56
    #5 0x7fd1558de82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

Thread T1 created by T0 here:
    #0 0x4457c3 in pthread_create (/home/fuzzer/libiec61850/build/examples/server_example_goose/server_example_goose+0x4457c3)
    #1 0x5d5cc5 in Thread_start /home/fuzzer/libiec61850/hal/thread/linux/thread_linux.c:101
    #2 0x4eb79a in IedServer_start /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:597
    #3 0x4d7cda in main /home/fuzzer/libiec61850/examples/server_example_goose/server_example_goose.c:66
    #4 0x7fd1558de82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-use-after-free /home/fuzzer/libiec61850/src/iec61850/server/impl/ied_server.c:556 singleThreadedServerThread
Shadow bytes around the buggy address:
  0x0c0e7fff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fd fd
  0x0c0e7fff9bc0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0e7fff9bd0: fd fd fd fd fd fa fa fa fa fa fd fd fd fd fd fd
  0x0c0e7fff9be0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c0e7fff9bf0: fd fa fa fa fa fa fd fd fd fd[fd]fd fd fd fd fd
  0x0c0e7fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c40: 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==14023==ABORTING
fuzzer@fuzzer:~/libiec61850/build/examples/server_example_goose$
```



Comments:
Comment by mzillgith on 2019-09-19 08:43:02+00:00:
Hello.
I cannot reproduce the problem. With branch v1.3 and v1.4 ASAN reports no problem when using the configuration you provided.

---

Comment by c0d3xpl0it on 2019-09-19 09:34:38+00:00:
Hello,

I was able to reproduce the issue with branch v1.3 on my setup. 

```
Machine : Ubuntu 16.04.3 LTS
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11)
```

Below are commands used.

```
git clone https://github.com/mz-automation/libiec61850
cd libiec61850/
mkdir build ; cd build
cmake .. -DCMAKE_CXX_FLAGS="-fsanitize=address -fsanitize=leak -g -ggdb -fno-omit-frame-pointer -static-libstdc++ -static-libasan" -DCMAKE_C_FLAGS="-fsanitize=address -fsanitize=leak -g -ggdb -fno-omit-frame-pointer -static-libstdc++ -static-libasan" -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address -fsanitize=leak -ggdb -fno-omit-frame-pointer -static-libstdc++ -static-libasan" -DCMAKE_MODULE_LINKER_FLAGS="-fsanitize=address -fsanitize=leak -ggdb -fno-omit-frame-pointer -static-libstdc++ -static-libasan"
AFL_USE_ASAN=1 make
cd examples/server_example_goose/
./server_example_goose  eth0
Using GOOSE interface: eth0
Starting server failed! Exit.
=================================================================
==15186==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000dfd0 at pc 0x0000004eb566 bp 0x7f776bcfee60 sp 0x7f776bcfee50
READ of size 8 at 0x60700000dfd0 thread T1
    #0 0x4eb565 in singleThreadedServerThread /home/fuzz/temp/libiec61850/src/iec61850/server/impl/ied_server.c:556
    #1 0x5d5c3c in destroyAutomaticThread /home/fuzz/temp/libiec61850/hal/thread/linux/thread_linux.c:90
    #2 0x7f776eec06b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
    #3 0x7f776e4d341c in clone (/lib/x86_64-linux-gnu/libc.so.6+0x10741c)

0x60700000dfd0 is located 32 bytes inside of 80-byte region [0x60700000dfb0,0x60700000e000)
freed by thread T0 here:
    #0 0x4a78fa in __interceptor_free (/home/fuzz/temp/libiec61850/build/examples/server_example_goose/server_example_goose+0x4a78fa)
    #1 0x5d662c in Memory_free /home/fuzz/temp/libiec61850/hal/memory/lib_memory.c:82
    #2 0x4eb497 in IedServer_destroy /home/fuzz/temp/libiec61850/src/iec61850/server/impl/ied_server.c:534
    #3 0x4d7d81 in main /home/fuzz/temp/libiec61850/examples/server_example_goose/server_example_goose.c:82
    #4 0x7f776e3ec82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

previously allocated by thread T0 here:
    #0 0x4a7dca in calloc (/home/fuzz/temp/libiec61850/build/examples/server_example_goose/server_example_goose+0x4a7dca)
    #1 0x5d65c5 in Memory_calloc /home/fuzz/temp/libiec61850/hal/memory/lib_memory.c:59
    #2 0x4ea824 in IedServer_createWithConfig /home/fuzz/temp/libiec61850/src/iec61850/server/impl/ied_server.c:394
    #3 0x4eb193 in IedServer_create /home/fuzz/temp/libiec61850/src/iec61850/server/impl/ied_server.c:484
    #4 0x4d7c5c in main /home/fuzz/temp/libiec61850/examples/server_example_goose/server_example_goose.c:56
    #5 0x7f776e3ec82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

Thread T1 created by T0 here:
    #0 0x4457c3 in pthread_create (/home/fuzz/temp/libiec61850/build/examples/server_example_goose/server_example_goose+0x4457c3)
    #1 0x5d5cc5 in Thread_start /home/fuzz/temp/libiec61850/hal/thread/linux/thread_linux.c:101
    #2 0x4eb79a in IedServer_start /home/fuzz/temp/libiec61850/src/iec61850/server/impl/ied_server.c:597
    #3 0x4d7cda in main /home/fuzz/temp/libiec61850/examples/server_example_goose/server_example_goose.c:66
    #4 0x7f776e3ec82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-use-after-free /home/fuzz/temp/libiec61850/src/iec61850/server/impl/ied_server.c:556 singleThreadedServerThread
Shadow bytes around the buggy address:
  0x0c0e7fff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fd fd
  0x0c0e7fff9bc0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0e7fff9bd0: fd fd fd fd fd fa fa fa fa fa fd fd fd fd fd fd
  0x0c0e7fff9be0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c0e7fff9bf0: fd fa fa fa fa fa fd fd fd fd[fd]fd fd fd fd fd
  0x0c0e7fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff9c40: 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==15186==ABORTING

```

Let me know if you can still reproduce the crash or not.


---

Comment by mzillgith on 2019-09-19 09:54:49+00:00:
Thanks for updated information.
I can now reproduce your ASAN output using Ubuntu 16.04.06. I tried before with Ubuntu 19.04 where the problem didn't show up.

---

Comment by mzillgith on 2019-09-19 13:55:44+00:00:
The problem was already fixed in v1.4 and should now also be fixed in v1.3 branch.

---

Comment by c0d3xpl0it on 2019-09-19 15:57:07+00:00:
[CVE-2019-16510](https://nvd.nist.gov/vuln/detail/CVE-2019-16510)

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 9881d248ec85e3be61cd29d048e3553be6974b4b
WORKDIR $SRC/libiec61850
COPY build.sh $SRC/

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