Project: imagemagick (imagemagick/imagemagick), language: c++
Vulnerability instance: imagemagick.cve-2021-3596
Sanitizer: address

================= Bug Report (1/2) ==================
## Source: GitHub Issue
## URL: https://github.com/ImageMagick/ImageMagick/issues/2624
## Description:
Issue: ImageMagick/ImageMagick#2624
Title: Null Pointer dereference caused by incomplete check of the return value from libxml2 in ReadSVGImage svg.c:3621
State: closed
Created by: 5hadowblad3
Created at: 2020-09-25 05:56:46+00:00

Issue Body:
### Prerequisites

- [Y ] I have written a descriptive issue title
- [Y] I have verified that I am using the latest version of ImageMagick
- [Y] I have searched [open](https://github.com/ImageMagick/ImageMagick/issues) and [closed](https://github.com/ImageMagick/ImageMagick/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported.

### Description
<!-- A description of the bug or feature -->
There is a segmentation fault caused by the NPD in function ReadSVGImage, svg.c:3621 in ImageMagick 7.0.10. 
ImageMagick does not check the nullity of the pointer returned from libxml2 and dereference it directly.
This directly leads to program crashes and segmentation fault.

### Steps to Reproduce
<!-- List of steps, sample code, failing test or link to a project that reproduces the behavior.
     Make sure you place a stack trace inside a code (```) block to avoid linking unrelated issues -->
1, To ensure reproduce, I  use up space in the  /tmp folder as a low-level privilege user.
For example, to facilitate the reproducation, 
~~~~
fallocate -l size_of_the_tmp_folder /tmp/test.img
~~~~

2, Run:
~~~~ 
magick convert poc ./test.ps
~~~~

[seg-svg3621.zip](https://github.com/ImageMagick/ImageMagick/files/5280857/seg-svg3621.zip) (unzip first)


Here is the trace reported by ASAN:
~~~~
ASAN:SIGSEGV
=================================================================
==112350==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010 (pc 0x0000009fec8c bp 0x62700001f900 sp 0x7ffd383e31c0 T0)
    #0 0x9fec8b in ReadSVGImage ../coders/svg.c:3621
    #1 0xc8ba0c in ReadImage ../MagickCore/constitute.c:553
    #2 0x8dfbc1 in ReadPESImage ../coders/pes.c:673
    #3 0xc8ba0c in ReadImage ../MagickCore/constitute.c:553
    #4 0xc8ecbc in ReadImages ../MagickCore/constitute.c:943
    #5 0x12bfaef in ConvertImageCommand ../MagickWand/convert.c:607
    #6 0x13fd865 in MagickCommandGenesis ../MagickWand/mogrify.c:191
    #7 0x43992d in MagickMain ../utilities/magick.c:149
    #8 0x7efd17fa982f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x439168 in _start (/mnt/data/playground/ImageMagick/build-asan/utilities/magick+0x439168)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ../coders/svg.c:3621 ReadSVGImage
==112350==ABORTING
~~~~

### System Configuration
<!-- Tell us about the environment where you are experiencing the bug -->
~~~~
CFLAGS='-I/usr/include/libxml2 -I/usr/include/libpng12  -I/usr/include/openjpeg-2.1 -I/usr/include/freetype2 -I/usr/include/freetype2  -fopenmp -Wall -O0 -g -fsanitize=address  -mtune=broadwell -fexceptions -pthread -DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16'
~~~~


- ImageMagick version:
Version: ImageMagick 7.0.10-31 Q16 x86_64 2020-09-22 https://imagemagick.org
Copyright: © 1999-2020 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.0) 
Delegates (built-in): bzlib fontconfig freetype jng jp2 jpeg lzma png x xml zlib

- Environment (Operating system, version and so on):
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
- Additional information:
<img width="1053" alt="image" src="https://user-images.githubusercontent.com/7632714/94231306-50f87b00-ff36-11ea-8d12-3e4aac41d28c.png">

Here is the link for the function xmlCreatePushParserCtxt in libxml2,
which indicates the return value can be NULL if fails.
https://gitlab.gnome.org/GNOME/libxml2/-/blob/master/parser.c#L12375
<img width="533" alt="image" src="https://user-images.githubusercontent.com/7632714/94231402-843b0a00-ff36-11ea-9eb0-ed51025e4671.png">


<!-- Thanks for reporting the issue to ImageMagick! -->



Comments:
Comment by dlemstra on 2020-09-25 18:07:31+00:00:
Thanks for the detailed report. We just pushed a patch to resolve this.

Attachments:
https://github.com/ImageMagick/ImageMagick/files/5280857/seg-svg3621.zip

================= Bug Report (2/2) ==================
## Source: Red Hat Bugzilla
## URL: https://bugzilla.redhat.com/show_bug.cgi?id=1970569
## Description:
Bugzilla ID: 1970569
Title: CVE-2021-3596 ImageMagick: NULL pointer dereference in ReadSVGImage() in coders/svg.c

Description
Guilherme de Almeida Suckevicz 2021-06-10 17:44:45 UTC
A NULL pointer dereference was found in ImageMagick in ReadSVGImage() in coders/svg.c because it does not check the return value from libxml2's xmlCreatePushParserCtxt() and use the value directly which can lead to crash and segmentation fault. This flaw affects ImageMagick versions prior to 7.0.10.31.

Reference:
https://github.com/ImageMagick/ImageMagick/issues/2624

Upstream patch:
https://github.com/ImageMagick/ImageMagick/commit/43dfb1894761c4929d5d5c98dc80ba4e59a0d114


Comments:
Comment 1
Guilherme de Almeida Suckevicz 2021-06-10 17:45:12 UTC
Created ImageMagick tracking bugs for this issue:

Affects: fedora-all [bug 1970570]

---

Comment 4
Product Security DevOps Team 2021-06-11 15:04:03 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2021-3596

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 make autoconf automake groff libtool pkg-config cmake nasm autopoint po4a libc6:i386 libc6-dev:i386
RUN apt-get install -y make autoconf automake groff libtool pkg-config cmake nasm autopoint po4a libc6:i386 libc6-dev:i386
RUN git clone https://github.com/imagemagick/imagemagick imagemagick
RUN git -C imagemagick checkout a8f9e86b0e8276ab5672cbf1ba927776c545afde
WORKDIR $SRC/imagemagick
COPY build.sh $SRC/

Additional files: