-
Notifications
You must be signed in to change notification settings - Fork 158
Description
I have the following PNG file, that is valid according to the PNG specification and has the following overall structure:
+-----------+-----+-----------+----------+
| Offset | Len | Type | CRC |
+-----------+-----+-----------+----------+
| 0x00000000| 8 | SIGNATURE | — |
| 0x00000008| 13 | IHDR | 9E2F6E4C |
| 0x00000021| 9 | pHYs | 38FE363B |
| 0x00000036| 4 | gAMA | 31E8965F |
| 0x00000046| 3 | sBIT | C79A0983 |
| 0x00000055| 774 | PLTE | 3FA76723 |
| 0x00000361| 256 | tRNS | 2F763A93 |
| 0x00000471| 1 | bKGD | F545D21B |
| 0x00000480| 31 | IDAT | 9D74E35B |
| 0x000004B0| 0 | IEND | AE426082 |
+-----------+-----+-----------+----------+
The file looks like this (base64):
iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAMAAACeL25MAAAACXBIWXMAAABFAAAARQE4/jY7AAAABGdBTUEAAYagMeiWXwAAAANzQklUBwcHx5oJgwAAAwZQTFRF/v7w
////AAAAAQEBAgICAwMDBAQEBQUFBgYGBwcHCAgICQkJCgoKCwsLDAwMDQ0NDg4ODw8PEBAQEREREhISExMTFBQUFRUVFhYWFxcXGBgYGRkZGhoaGxsbHBwcHR0dHh4e
Hx8fICAgISEhIiIiIyMjJCQkJSUlJiYmJycnKCgoKSkpKioqKysrLCwsLS0tLi4uLy8vMDAwMTExMjIyMzMzNDQ0NTU1NjY2Nzc3ODg4OTk5Ojo6Ozs7PDw8PT09Pj4+
Pz8/QEBAQUFBQkJCQ0NDRERERUVFRkZGR0dHSEhISUlJSkpKS0tLTExMTU1NTk5OT09PUFBQUVFRUlJSU1NTVFRUVVVVVlZWV1dXWFhYWVlZWlpaW1tbXFxcXV1dXl5e
X19fYGBgYWFhYmJiY2NjZGRkZWVlZmZmZ2dnaGhoaWlpampqa2trbGxsbW1tbm5ub29vcHBwcXFxcnJyc3NzdHR0dXV1dnZ2d3d3eHh4eXl5enp6e3t7fHx8fX19fn5+
f39/gICAgYGBgoKCg4ODhISEhYWFhoaGh4eHiIiIiYmJioqKi4uLjIyMjY2Njo6Oj4+PkJCQkZGRkpKSk5OTlJSUlZWVlpaWl5eXmJiYmZmZmpqam5ubnJycnZ2dnp6e
n5+foKCgoaGhoqKio6OjpKSkpaWlpqamp6enqKioqampqqqqq6urrKysra2trq6ur6+vsLCwsbGxsrKys7OztLS0tbW1tra2t7e3uLi4ubm5urq6u7u7vLy8vb29vr6+
v7+/wMDAwcHBwsLCw8PDxMTExcXFxsbGx8fHyMjIycnJysrKy8vLzMzMzc3Nzs7Oz8/P0NDQ0dHR0tLS09PT1NTU1dXV1tbW19fX2NjY2dnZ2tra29vb3Nzc3d3d3t7e
39/f4ODg4eHh4uLi4+Pj5OTk5eXl5ubm5+fn6Ojo6enp6urq6+vr7Ozs7e3t7u7u7+/v8PDw8fHx8vLy8/Pz9PT09fX19vb29/f3+Pj4+fn5+vr6+/v7/Pz8/f39/v7+
////P6dnIwAAAQB0Uk5TAAD/AAAAAAAA/wAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAA
AAAAAAD/AAAAAP8AAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA/wAAAAD/AAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAC92OpMAAAABYktHRPVF0hvb
AAAAH0lEQVR4AQEUAOv/AAn5EQIAnXTjWwDYQVbFAGNWiMBFfweaa4QwDwAAAABJRU5ErkJggg==
When parsing this file with image-png, the parser crashes with an OOB write while assigning the parsed palette to the image object in create_rgba_palette (palette.rs).
The reason for this OOB write is a missing length check when writing into the fixed-size rgba_palette array initialized in line 57.
The PNG specification does not limit the maximum length of a palette, but only requires that each color index used in image data is present in the provided palette. Thus an over-long palette is valid according to the PNG specification, although those superfluous entries are useless. When assigning the palette, at most as many entries as fit into the indexable palette should be copied. In 6b1a53d a check was introduced in stream.rs (around line 1040ff) that tries to validate the expected lengths for various chunks and by accident makes the buggy code unreachable.
Furthermore, as a side-note, shorter palettes are valid IF AND ONLY IF no actual pixel data references unassigned palette indices. This constraint is not validated by the parser, thus accepting PNG files that are invalid according to the PNG specification.
Co-Authored-By: @stoeckmann