Project: libplist (libimobiledevice/libplist), language: c++
Vulnerability instance: libplist.cve-2017-6439
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/libimobiledevice/libplist/issues/95
## Description:
Issue: libimobiledevice/libplist#95
Title: heap-buffer-overflow in parse_string_node
State: closed
Created by: zhunki
Created at: 2017-02-08 05:08:19+00:00

Issue Body:
```
==4536== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb5e0074e at pc 0x806616b bp 0xbfabe008 sp 0xbfabdffc
WRITE of size 1 at 0xb5e0074e thread T0
    #0 0x806616a in parse_string_node /home/b/asan/libplist/src/bplist.c:298
    #1 0x806616a in parse_bin_node /home/b/asan/libplist/src/bplist.c:668
    #2 0x806616a in parse_bin_node_at_index /home/b/asan/libplist/src/bplist.c:755
    #3 0x80632a0 in parse_dict_node /home/b/asan/libplist/src/bplist.c:461
    #4 0x80632a0 in parse_bin_node /home/b/asan/libplist/src/bplist.c:697
    #5 0x80632a0 in parse_bin_node_at_index /home/b/asan/libplist/src/bplist.c:755
    #6 0x8068b30 in plist_from_bin /home/b/asan/libplist/src/bplist.c:844
    #7 0x804a175 in main /home/b/asan/libplist/tools/plistutil.c:150
    #8 0xb5f9ba82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
    #9 0x804aef5 in _start (/home/b/asan/libplist/tools/plistutil+0x804aef5)
0xb5e0074e is located 2 bytes to the left of 1-byte region [0xb5e00750,0xb5e00751)
allocated by thread T0 here:
    #0 0xb6163854 (/usr/lib/i386-linux-gnu/libasan.so.0+0x16854)
    #1 0x8063b7c in parse_string_node /home/b/asan/libplist/src/bplist.c:292
    #2 0x8063b7c in parse_bin_node /home/b/asan/libplist/src/bplist.c:668
    #3 0x8063b7c in parse_bin_node_at_index /home/b/asan/libplist/src/bplist.c:755
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/b/asan/libplist/src/bplist.c:298 parse_string_node
Shadow bytes around the buggy address:
  0x36bc0090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc00a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc00b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc00c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc00d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x36bc00e0: fa fa fa fa fa fa fa fa fa[fa]01 fa fa fa 00 04
  0x36bc00f0: fa fa 00 04 fa fa 00 04 fa fa 00 04 fa fa 00 04
  0x36bc0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc0110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc0120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc0130: 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 righ 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
  ASan internal:         fe
```
[poc.txt](https://github.com/libimobiledevice/libplist/files/759765/poc.txt)



Comments:
Comment by nikias on 2017-02-15 14:46:22+00:00:
Can you please re-run with lastet code? AFAIK this was fixed with commit 32ee5213fe64f1e10ec76c1ee861ee6f233120dd.

---

Comment by carnil on 2017-03-16 06:04:12+00:00:
This is CVE-2017-6439

Attachments:
https://github.com/libimobiledevice/libplist/files/759765/poc.txt

Commit References:
32ee5213fe64f1e10ec76c1ee861ee6f233120dd

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
./autogen.sh --without-cython --enable-debug
make -j$(nproc) clean
make -j$(nproc) all

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get install -y make autoconf automake libtool pkg-config
RUN git clone https://github.com/libimobiledevice/libplist libplist
RUN git -C libplist checkout 72f7cf803635a127c63bcd37ab35ced28636410a
WORKDIR $SRC/libplist
COPY build.sh $SRC/

Additional files:
filename: bplist.dict
content: header_bplist = "bplist00"

filename: bplist_fuzzer.cc
content: /*
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
*/

#include <plist/plist.h>
#include <stdio.h>

extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size)
{
	plist_t root_node = NULL;
	plist_from_bin(reinterpret_cast<const char*>(data), size, &root_node);
	plist_free(root_node);

	return 0;
}

filename: bplist_fuzzer.options
content: [libfuzzer]
max_len = 4096
dict = bplist.dict

filename: xplist.dict
content: # Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
# AFL dictionary for XML Property Lists
# ----------------------
#
# Several basic syntax elements and attributes for libplist.
#
# Created by Nikias Bassen <nikias@gmx.li>
# Adapted from libxml2's dict file (created by Michal Zalewski <lcamtuf@google.com>)
#

attr_encoding=" encoding=\"1\""
attr_generic=" a=\"1\""
attr_version=" version=\"1\""

entity_builtin="&lt;"
entity_decimal="&#1;"
entity_external="&a;"
entity_hex="&#x1;"

string_cdata="CDATA"
string_dashes="--"
string_empty="EMPTY"
string_empty_dblquotes="\"\""
string_empty_quotes="''"
string_parentheses="()"
string_pcdata="#PCDATA"
string_percent="%a"
string_public="PUBLIC"
string_utf8="UTF-8"

tag_cdata="<![CDATA["
tag_close="</plist>"
tag_doctype="<!DOCTYPE"
tag_open="<plist>"
tag_open_close="<plist />"
tag_open_exclamation="<!"
tag_open_q="<?"
tag_sq2_close="]]>"
tag_xml_q="<?xml?>"
tag_array="<array>"
tag_data="<data>"
tag_date="<date>"
tag_dict="<dict>"
tag_false="<false/>"
tag_integer="<integer>"
tag_key="<key>"
tag_plist="<plist>"
tag_real="<real>"
tag_string="<string>"
tag_true="<true/>"

filename: xplist_fuzzer.cc
content: /*
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
*/

#include <plist/plist.h>
#include <stdio.h>

extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size)
{
	plist_t root_node = NULL;
	plist_from_xml(reinterpret_cast<const char*>(data), size, &root_node);
	plist_free(root_node);

	return 0;
}

filename: xplist_fuzzer.options
content: [libfuzzer]
max_len = 4096
dict = xplist.dict