michaelrsweet / htmldoc

HTML Conversion Software
https://www.msweet.org/htmldoc
GNU General Public License v2.0
206 stars 46 forks source link

Double free in image_load_png() #462

Closed 00xc closed 2 years ago

00xc commented 2 years ago

In image_load_png(), in image.cxx, the rows variable is free()'d twice whenever there is an error during png_read_end():

static int          /* O - 0 = success, -1 = fail */
image_load_png(image_t *img,    /* I - Image pointer */
               FILE    *fp, /* I - File to read from */
               int     gray,    /* I - 0 = color, 1 = grayscale */
               int     load_data)/* I - 1 = load image data, 0 = just info */
{
  /* ... */
  png_bytep *rows;      /* PNG row pointers */

  /* ... */

  rows = NULL;

  if (setjmp(png_jmpbuf(pp)))
  {
    progress_error(HD_ERROR_BAD_FORMAT, "PNG file contains errors!");

    /* ... */

    if (rows != NULL)
      free(rows);

    return (-1);
  }

  /* ... */

  free(rows);

  png_read_end(pp, info);
  png_destroy_read_struct(&pp, &info, NULL);

  return (0);
}

Before calling png_read_end(), the rows variable is freed but not set to NULL. If png_read_end() fails, the program will jump to png_jmpbuf, which will attempt to free rows again.

This bug is considered a security issue (CWE-415) under certain circumstances. An attacker is able to trigger this condition by linking a maliciously crafted PNG file in an HTML document.

Reproducer

  1. git clone https://github.com/michaelrsweet/htmldoc && cd htmldoc
  2. ./configure && make -j$(nproc)
  3. ./htmldoc/htmldoc --webpage -f out.pdf ./poc.html

Result:

$ ./htmldoc/htmldoc --webpage -f out.pdf ./poc.html
...
libpng error: PNG unsigned integer out of range
ERR007: PNG file contains errors!
ERR011: Unable to load image file "./poc.png"!
free(): double free detected in tcache 2

htmldoc_poc1.zip

michaelrsweet commented 2 years ago

@00xc Thanks for this, fixed:

[master 5495336] Fix a potential double-free bug when loading PNG images (Issue #462)