Package: libgdiplus
Version: 3.6-1+b2
Severity: normal
Tags: upstream patch

Hi,

there is gdip_load_png_image_from_file_or_stream() in src/pngcodec.c
which calls png_get_PLTE() without initializing the result parameters
before or checking for the 0 (error) return code after. This leads to
png_palette and num_palette being uninitialized when loading certain
images. png_palette is dereferenced, then, in line 378 and following:

                                          set_pixel_bgra(&palette->Entries[i], 
0,
                                                          png_palette[i].blue,
                                                          png_palette[i].green,
                                                          png_palette[i].red,
  #if PNG_LIBPNG_VER > 10399
                                                          trans_alpha [i]); /* 
alpha */
  #else
                                                          info_ptr->trans[i]); 
/* alpha */
  #endif

Depending on unknown factors, png_palette is sometimes some valid
pointer then, and png_palette[i].blue, .green, .red read from a random
memory location; or in other cases png_palette is 0, 0x2, 0x2c or other
values that are not accessible when interpreted as an address. This
then leads to the Mono application crashing in native code.

I've included a patch that initializes png_palette and num_palette to
zero. If png_get_PLTE() failed, and therefore those variables stay zero,
this should trigger a check in line 337/338 that sets palette_entries to
zero, which will cause the for loop that contains the set_pixel_bgra()
call to be skipped completely.

Note that this only fixes the crashes. It could be the case that a fully
transparent image (consisting of fully transparent pixels only) would be
loaded as, e.g., a completely black image, with this code change. Other
places where libgdiplus crashes on this type of image might exist, too.


To test the crash - although this might not crash even if it is still
buggy - run this:

  $ csharp /r:System.Drawing
  Mono C# Shell, type "help;" for help
  
  Enter statements below.
  csharp> using System.Drawing;
  csharp> Bitmap bmpTest = new Bitmap("explosion00.png");

After this it might crash if you're (un)lucky.

Regards, Fabian Pietsch

-- System Information:
Debian Release: 8.1
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 3.16.0-4-686-pae (SMP w/1 CPU core)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)

Versions of packages libgdiplus depends on:
ii  libc6            2.19-18
ii  libcairo2        1.14.0-2.1
ii  libexif12        0.6.21-2
ii  libfontconfig1   2.11.0-6.3
ii  libfreetype6     2.5.2-3
ii  libgif4          4.1.6-11
ii  libglib2.0-0     2.42.1-1
ii  libjpeg62-turbo  1:1.3.1-12
ii  libpng12-0       1.2.50-2+b2
ii  libtiff5         4.0.3-12.3
ii  libx11-6         2:1.6.2-3
ii  libxrender1      1:0.9.8-1+b1

libgdiplus recommends no packages.

libgdiplus suggests no packages.

-- no debconf information
--- src/pngcodec.c.orig	2015-07-02 19:31:59.000000000 +0200
+++ src/pngcodec.c	2015-07-03 00:14:25.000000000 +0200
@@ -248,10 +248,10 @@
 	GpStatus	status = InvalidParameter;
 	int		bit_depth;
 	int		channels;
 	BYTE		color_type;
-	int 	num_palette;
-	png_colorp	png_palette;
+	int 		num_palette = 0;
+	png_colorp	png_palette = NULL;
 
 	png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 
 	if (!png_ptr) {

Reply via email to