[mupen64plus] 130/262: Fix crash when loading png due to reordering optimizer

Sven Eckelmann ecsv-guest at moszumanska.debian.org
Thu Nov 26 05:59:26 UTC 2015


This is an automated email from the git hooks/post-receive script.

ecsv-guest pushed a commit to branch master
in repository mupen64plus.

commit 55f1f6e5f9d6e67fc3a3c3413d6f9c92146e6cdb
Author: Sven Eckelmann <sven.eckelmann at gmx.de>
Date:   Mon Sep 21 22:24:46 2009 +0200

    Fix crash when loading png due to reordering optimizer
    
    The optimizer can reorder instructions like the initialisation of
    variables if it looks safe to him. It isn't said that all variables are
    initialised right before the call of the first setjmp and thus we cannot
    rely on there value to determine if they are point to actual data.
---
 debian/changelog                 |   2 +
 debian/patches/fix_readpng.patch | 291 +++++++++++++++++++++++++++++++++++++++
 debian/patches/series            |   1 +
 3 files changed, 294 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 0ad302e..3fc174f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,6 +7,8 @@ mupen64plus (1.5+dfsg1-5) UNRELEASED; urgency=low
       filtered open file dialog (Closes: #546046)
     - Add noexecstack.patch, Don't enable executable stack by default
       (Closes: #547644)
+    - Add fix_readpng.patch, Fix crash when loading png due to reordering
+      optimizer
 
  -- Sven Eckelmann <sven.eckelmann at gmx.de>  Fri, 11 Sep 2009 00:37:19 +0200
 
diff --git a/debian/patches/fix_readpng.patch b/debian/patches/fix_readpng.patch
new file mode 100644
index 0000000..d44b219
--- /dev/null
+++ b/debian/patches/fix_readpng.patch
@@ -0,0 +1,291 @@
+Description: Fix crash when loading png due to reordering optimizer
+ The optimizer can reorder instructions like the initialisation of variables if
+ it looks safe to him. It isn't said that all variables are initialised right
+ before the call of the first setjmp and thus we cannot rely on there value to
+ determine if they are point to actual data.
+Bug: http://code.google.com/p/mupen64plus/issues/detail?id=209
+Author: Sven Eckelmann <sven.eckelmann at gmx.de>
+
+---
+diff --git a/rice_video/liblinux/bmp.c b/rice_video/liblinux/bmp.c
+index 13c66fdc427c6fc94bff5e3434a1067199d7353f..877e376d1f3c59228027330375f9b40090ef8cef 100644
+--- a/rice_video/liblinux/bmp.c
++++ b/rice_video/liblinux/bmp.c
+@@ -206,7 +206,6 @@ BMGError WriteBMP( const char *filename,
+                    struct BMGImageStruct img )
+ {
+     FILE *file = NULL;
+-    jmp_buf err_jmp;
+     int error;
+ 
+     unsigned char *bits = NULL;
+@@ -223,30 +222,24 @@ BMGError WriteBMP( const char *filename,
+ 
+     SetLastBMGError( BMG_OK );
+ 
+-    /* error handler */
+-    error = setjmp( err_jmp );
+-    if ( error != 0 )
+-    {
+-        if ( file != NULL )
+-            fclose( file );
+-        if ( bits != NULL )
+-            free( bits );
+-        if ( pColor != NULL )
+-            free( pColor );
+-        SetLastBMGError( (BMGError)error );
+-        return (BMGError)error;
++    if ( img.bits == NULL ) {
++        SetLastBMGError( errInvalidBMGImage );
++        return errInvalidBMGImage;
+     }
+ 
+-    if ( img.bits == NULL )
+-        longjmp( err_jmp, (int)errInvalidBMGImage );
+-
+     file = fopen( filename, "wb" );
+-    if ( file == NULL )
+-        longjmp( err_jmp, (int)errFileOpen );
++    if ( file == NULL ) {
++        fclose( file );
++        SetLastBMGError( errFileOpen );
++        return errFileOpen;
++    }
+ 
+     /* abort if we do not support the data */
+-    if ( img.palette != NULL && img.bytes_per_palette_entry < 3 )
+-        longjmp( err_jmp, (int)errInvalidBMGImage );
++    if ( img.palette != NULL && img.bytes_per_palette_entry < 3 ) {
++        fclose( file );
++        SetLastBMGError( errInvalidBMGImage );
++        return errInvalidBMGImage;
++    }
+ 
+     /* calculate dimensions */
+     BitsPerPixel = img.bits_per_pixel < 32 ? img.bits_per_pixel : 24U;
+@@ -259,8 +252,11 @@ BMGError WriteBMP( const char *filename,
+     /* allocate memory for bit array - assume that compression will
+     // actually compress the bitmap */
+     bits = (unsigned char *)calloc( bit_size, 1 );
+-    if ( bits == NULL )
+-        longjmp( err_jmp, (int)errMemoryAllocation );
++    if ( bits == NULL ) {
++        fclose( file );
++        SetLastBMGError( errMemoryAllocation );
++        return errMemoryAllocation;
++    }
+ 
+     /* some initialization */
+     memset( (void *)&bmih, 0, sizeof(BITMAPINFOHEADER) );
+@@ -312,8 +308,12 @@ BMGError WriteBMP( const char *filename,
+     if ( img.palette != NULL )
+     {
+         pColor = (unsigned char *)calloc( img.palette_size, sizeof(RGBQUAD) );
+-        if ( pColor == NULL )
+-            longjmp( err_jmp, (int)errMemoryAllocation );
++        if ( pColor == NULL ) {
++            free( bits );
++            fclose( file );
++            SetLastBMGError( errMemoryAllocation );
++            return errMemoryAllocation;
++        }
+ 
+         if ( img.bytes_per_palette_entry == 3 )
+         {
+@@ -338,31 +338,43 @@ BMGError WriteBMP( const char *filename,
+                      img.palette_size * sizeof(RGBQUAD);
+     bmfh.bfSize = bmfh.bfOffBits + bit_size;
+ 
+-    if ( fwrite( (void *)&bmfh, sizeof(BITMAPFILEHEADER), 1, file ) != 1 )
+-        longjmp( err_jmp, (int)errFileWrite );
++    if ( fwrite( (void *)&bmfh, sizeof(BITMAPFILEHEADER), 1, file ) != 1 ) {
++        free( pColor );
++        free( bits );
++        fclose( file );
++        SetLastBMGError( errFileWrite );
++        return errFileWrite;
++    }
+ 
+-    if ( fwrite( (void *)&bmih, sizeof(BITMAPINFOHEADER), 1, file ) != 1 )
+-        longjmp( err_jmp, (int)errFileWrite );
++    if ( fwrite( (void *)&bmih, sizeof(BITMAPINFOHEADER), 1, file ) != 1 ) {
++        free( pColor );
++        free( bits );
++        fclose( file );
++        SetLastBMGError( errFileWrite );
++        return errFileWrite;
++    }
+ 
+-    if ( pColor != NULL )
+-    {
+-        if ( fwrite( (void *)pColor, sizeof(RGBQUAD), img.palette_size, file )
+-                              != (unsigned int)img.palette_size )
+-        {
+-            longjmp( err_jmp, (int)errFileWrite );
+-        }
++    if ( fwrite( (void *)pColor, sizeof(RGBQUAD), img.palette_size, file )
++                              != (unsigned int)img.palette_size ) {
++        free( pColor );
++        free( bits );
++        fclose( file );
++        SetLastBMGError( errFileWrite );
++        return errFileWrite;
+     }
+ 
+     if ( fwrite( (void *)bits, sizeof(unsigned char), bit_size, file )
+-                    != bit_size )
+-    {
+-        longjmp( err_jmp, (int)errFileWrite );
++                    != bit_size ) {
++        free( pColor );
++        free( bits );
++        fclose( file );
++        SetLastBMGError( errFileWrite );
++        return errFileWrite;
+     }
+ 
+     fclose( file );
+     free( bits );
+-    if ( pColor != NULL )
+-        free( pColor );
++    free( pColor );
+     return BMG_OK;
+ }
+ 
+diff --git a/rice_video/liblinux/pngrw.c b/rice_video/liblinux/pngrw.c
+index 673741adbc1d75499100624572a6512fdefd39dc..e9985e873b9280670b5c11fb848833ac5b37713e 100644
+--- a/rice_video/liblinux/pngrw.c
++++ b/rice_video/liblinux/pngrw.c
+@@ -109,13 +109,14 @@ BMGError ReadPNG( const char *filename,
+     unsigned char       signature[8];
+     png_structp         png_ptr = NULL;
+     png_infop           info_ptr = NULL;
++    png_infop           end_info = NULL;
+     png_colorp          PNGPalette = NULL;
+     png_color_16       *ImageBackground = NULL;
+     png_bytep           trns = NULL;
+     int                 NumTrans = 0;
+     int                 i, j, k;
+     png_color_16p       TransColors = NULL;
+-    unsigned int        Width, Height;
++    png_uint_32         Width, Height;
+ 
+     unsigned char      *bits, *p, *q;
+     unsigned char**     rows = NULL;
+@@ -128,53 +129,63 @@ BMGError ReadPNG( const char *filename,
+     BMGError tmp;
+     unsigned int DIBLineWidth;
+ 
+-    /* error handler */
+-    error = setjmp( err_jmp );
+-    if ( error != 0 )
+-    {
+-        if ( png_ptr != NULL )
+-            png_destroy_read_struct( &png_ptr, NULL, NULL );
+-        if ( rows )
+-        {
+-            if ( rows[0] )
+-                free( rows[0] );
+-            free( rows );
+-        }
+-        FreeBMGImage( img );
+-        fclose( file );
+-        SetLastBMGError( (BMGError)error );
++    if ( img == NULL ) {
++        SetLastBMGError( errInvalidBMGImage );
+         return (BMGError)error;
+     }
+ 
+-    if ( img == NULL )
+-        longjmp ( err_jmp, (int)errInvalidBMGImage );
+-
+     file = fopen( filename, "rb" );
+-    if ( !file )
+-        longjmp ( err_jmp, (int)errFileOpen );
++    if ( !file ) {
++        SetLastBMGError( errFileOpen );
++        return errFileOpen;
++    }
+ 
+     /* check the signature */
+     fread( signature, 1, 8, file );
+-    if ( !png_check_sig( signature, 8 ) )
+-        longjmp( err_jmp, (int)errUnsupportedFileFormat );
++    if ( !png_check_sig( signature, 8 ) ) {
++        fclose(file);
++        SetLastBMGError( errUnsupportedFileFormat );
++        return errUnsupportedFileFormat;
++    }
+ 
+     /* create a pointer to the png read structure */
+     png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
+-    if ( !png_ptr )
+-        longjmp( err_jmp, (int)errMemoryAllocation );
++    if ( !png_ptr ) {
++        fclose(file);
++        SetLastBMGError( errMemoryAllocation );
++        return errMemoryAllocation;
++    }
++
++    /* create a pointer to the png info structure */
++    info_ptr = png_create_info_struct( png_ptr );
++    if ( !info_ptr ) {
++        fclose(file);
++	png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
++        SetLastBMGError( errMemoryAllocation );
++        return errMemoryAllocation;
++    }
++
++    end_info = png_create_info_struct(png_ptr);
++    if (!end_info)
++    {
++        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
++        SetLastBMGError( errMemoryAllocation );
++        return errMemoryAllocation;
++    }
+ 
+     /* bamboozle the PNG longjmp buffer */
+     /*generic PNG error handler*/
+     /* error will always == 1 which == errLib */
+ //    error = png_setjmp(png_ptr);
+-    error = setjmp( png_jmpbuf( png_ptr ) );
+-    if ( error > 0 )
+-        longjmp( err_jmp, error );
+-
+-    /* create a pointer to the png info structure */
+-    info_ptr = png_create_info_struct( png_ptr );
+-    if ( !info_ptr )
+-        longjmp( err_jmp, (int)errMemoryAllocation );
++    error = setjmp(png_jmpbuf(png_ptr));
++    if ( error != 0 )
++    {
++        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
++        FreeBMGImage( img );
++        fclose( file );
++        SetLastBMGError( (BMGError)error );
++        return (BMGError)error;
++    }
+ 
+     /* attach file buffer to the png read pointer */
+     png_init_io( png_ptr, file );
+@@ -187,7 +198,7 @@ BMGError ReadPNG( const char *filename,
+ 
+     /* extract the data we need to form the HBITMAP from the PNG header */
+     png_get_IHDR( png_ptr, info_ptr, &Width, &Height, &BitDepth, &ColorType,
+-        &InterlaceType, NULL, NULL );
++        &InterlaceType, int_p_NULL, int_p_NULL );
+ 
+     img->width = Width;
+     img->height = Height;
+@@ -356,8 +367,10 @@ BMGError ReadPNG( const char *filename,
+ 
+     k = png_get_rowbytes( png_ptr, info_ptr );
+     rows[0] = (unsigned char *)malloc( Height*k*sizeof(char));
+-    if ( !rows[0] )
++    if ( !rows[0] ) {
++        free( rows );
+         longjmp( err_jmp, (int)errMemoryAllocation );
++    }
+ 
+     for ( i = 1; i < (int)Height; i++ )
+         rows[i] = rows[i-1] + k;
diff --git a/debian/patches/series b/debian/patches/series
index ab3d2a8..51573fd 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -23,3 +23,4 @@ version-string.patch
 default-optimisations.patch
 gtk-open-filter.patch
 noexecstack.patch
+fix_readpng.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/mupen64plus.git



More information about the Pkg-games-commits mailing list