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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/libimobiledevice/libplist/issues/103
## Description:
Issue: libimobiledevice/libplist#103
Title: heap-buffer-overflow in bplist.c:733
State: closed
Created by: zhunki
Created at: 2017-04-18 07:06:33+00:00

Issue Body:
```
==26853== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb58018c8 at pc 0x80665b8 bp 0xbfb96b58 sp 0xbfb96b4c
READ of size 8 at 0xb58018c8 thread T0
    #0 0x80665b7 in parse_bin_node_at_index /home/b/libplist/src/bplist.c:733
    #1 0x8069720 in plist_from_bin /home/b/libplist/src/bplist.c:857
    #2 0x804bbab in main /home/b/libplist/tools/plistutil.c:150
    #3 0xb5fe6a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
    #4 0x804c805 in _start (/home/b/libplist/tools/plistutil+0x804c805)
0xb58018c8 is located 24 bytes to the left of 0-byte region [0xb58018e0,0xb58018e0)
==26853== AddressSanitizer CHECK failed: ../../../../src/libsanitizer/asan/asan_allocator2.cc:216 "((id)) != (0)" (0x0, 0x0)
    #0 0xb61aa4b2 (/usr/lib/i386-linux-gnu/libasan.so.0+0x124b2)
    #1 0xb61b30dc (/usr/lib/i386-linux-gnu/libasan.so.0+0x1b0dc)
    #2 0xb619bf1e (/usr/lib/i386-linux-gnu/libasan.so.0+0x3f1e)
    #3 0xb61b06e3 (/usr/lib/i386-linux-gnu/libasan.so.0+0x186e3)
    #4 0xb61b1b8f (/usr/lib/i386-linux-gnu/libasan.so.0+0x19b8f)
    #5 0xb61aa9ee (/usr/lib/i386-linux-gnu/libasan.so.0+0x129ee)
    #6 0x80665b7 in parse_bin_node_at_index /home/b/libplist/src/bplist.c:733
    #7 0x8069720 in plist_from_bin /home/b/libplist/src/bplist.c:857
    #8 0x804bbab in main /home/b/libplist/tools/plistutil.c:150
    #9 0xb5fe6a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
    #10 0x804c805 in _start (/home/b/libplist/tools/plistutil+0x804c805)
Aborted
```
[bplist_c_733.txt](https://github.com/libimobiledevice/libplist/files/927598/bplist_c_733.txt)



Comments:
Comment by nikias on 2017-04-18 11:39:56+00:00:
I cannot reproduce it. This check prevents further processing for me:
https://github.com/libimobiledevice/libplist/blob/master/src/bplist.c#L837
```
    if ((uint64_t)offset_table + num_objects * offset_size > (uint64_t)end_data) {
        PLIST_BIN_ERR("offset table points outside of valid range\n");
        return;
    }
```
It is supposed to prevent that the number of objects combined with the offset size will point outside of the plist data. The sample you provided has number of objects = 0x8000000000000003 and offset size = 0xFF. Maybe your compiler reduces the sizes to 32 bit? Strangely enough, even then it would point outside of the plist data...

---

Comment by nikias on 2017-04-18 21:15:10+00:00:
@zhunki can you use this patch and paste the output:
```
diff --git a/src/bplist.c b/src/bplist.c
index eede7a7..07084f6 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -834,6 +834,11 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t *
         return;
     }

+printf("offset_table: 0x%llx\n", (uint64_t)offset_table);
+printf("num_objects: 0x%llx\n", num_objects);
+printf("offset_size: 0x%x\n", offset_size);
+printf("end_data: 0x%llx\n", (uint64_t)end_data);
+printf("range check: 0x%llx > 0x%llx\n", (uint64_t)offset_table + num_objects * offset_size, (uint64_t)end_data);
     if ((uint64_t)offset_table + num_objects * offset_size > (uint64_t)end_data) {
         PLIST_BIN_ERR("offset table points outside of valid range\n");
         return;
```

---

Comment by zhunki on 2017-04-19 03:23:18+00:00:
@nikias the result is as follows
offset_table: 0xffffffffb58017d1
num_objects: 0x8000000000000003
offset_size: 0xff
end_data: 0xffffffffb58017d4
range check: 0x7fffffffb5801ace > 0xffffffffb58017d4


ps. 0x8000000000000003*0xff=0x‭80000000000002FD
integer overflowed.
0x‭80000000000002FD+0xffffffffb58017d1=‭0x7FFFFFFFB5801ACE‬
integer overflowed again.

I'm using gcc, maybe your conpiler is defferent and can handle such case?

---

Comment by nikias on 2017-04-19 17:58:44+00:00:
@zhunki should be fixed with my latest commit: fdebf8b319b9280cd0e9b4382f2c7cbf26ef9325

---

Comment by zhunki on 2017-04-20 02:56:11+00:00:
@nikias sure. well done.

Attachments:
https://github.com/libimobiledevice/libplist/files/927598/bplist_c_733.txt

Commit References:
fdebf8b319b9280cd0e9b4382f2c7cbf26ef9325

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

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

Additional files: