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) {