LibPNG 1.2.5 - 'png_jmpbuf()' Local Buffer Overflow

Author: anonymous
type: local
platform: linux
port: 
date_added: 2004-08-12  
date_updated: 2016-03-30  
verified: 1  
codes: OSVDB-8326;CVE-2004-0597  
tags:   
aliases:   
screenshot_url:   
application_url: http://www.exploit-db.comlibpng-1.2.5.tar.gz  

raw file: 393.c  
#include <stdio.h>
#include <stdlib.h>
#include "png.h"

/* The png_jmpbuf() macro, used in error handling, became available in
  * libpng version 1.0.6.   If you want to be able to run your code with older
  * versions of libpng, you must define the macro yourself (but only if it
  * is not already defined by libpng!).
  */

#ifndef png_jmpbuf
#define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
#endif
#define ERROR 1
#define OK 0

int read_png(char *file_name)   /* We need to open the file */
{
  png_structp png_ptr;
  png_infop info_ptr;
  unsigned int sig_read = 0;
  png_uint_32 width, height;
  int bit_depth, color_type, interlace_type;
  FILE *fp;

  if ((fp = fopen(file_name, "rb")) == NULL)
      return (ERROR);

  /* Create and initialize the png_struct with the desired error handler
    * functions.   If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.   We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.   REQUIRED
    */
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
      NULL, NULL, NULL);

  if (png_ptr == NULL)
  {
      fclose(fp);
      return (ERROR);
  }

  /* Allocate/initialize the memory for image information.   REQUIRED. */
  info_ptr = png_create_info_struct(png_ptr);
  if (info_ptr == NULL)
  {
      fclose(fp);
      png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
      return (ERROR);
  }

  /* Set error handling if you are using the setjmp/longjmp method (this is
    * the normal method of doing things with libpng).   REQUIRED unless you
    * set up your own error handlers in the png_create_read_struct() earlier.
    */
  if (setjmp(png_jmpbuf(png_ptr)))
  {
      /* Free all of the memory associated with the png_ptr and info_ptr */
      png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
      fclose(fp);
      /* If we get here, we had a problem reading the file */
      return (ERROR);
  }

  /* Set up the input control if you are using standard C streams */
  png_init_io(png_ptr, fp);

  /* If we have already read some of the signature */
  png_set_sig_bytes(png_ptr, sig_read);

  /*
    * If you have enough memory to read in the entire image at once,
    * and you need to specify only transforms that can be controlled
    * with one of the PNG_TRANSFORM_* bits (this presently excludes
    * dithering, filling, setting background, and doing gamma
    * adjustment), then you can read the entire image (including
    * pixels) into the info structure with this call:
    */
  png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);

  /* clean up after the read, and free any memory allocated - REQUIRED */
  png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);

  /* close the file */
  fclose(fp);

  /* that's it */
  return (OK);
}

int main(int argc, char **argv)
{

    if(argc < 2){
        fprintf(stderr, "Usage: %s <png>n", argv[0]);
        return EXIT_FAILURE;
    }

    if(read_png(argv[1]) != OK){
        fprintf(stderr, "Error reading pngn");
        return EXIT_FAILURE;
    }

    return 0;
}

// milw0rm.com [2004-08-13]