After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 739133 - (CVE-2017-17785) CVE-2017-17785 Out of bounds write / heap overflow in the .fli importer / fli_read_brun
(CVE-2017-17785)
CVE-2017-17785 Out of bounds write / heap overflow in the .fli importer / fli...
Status: RESOLVED FIXED
Product: GIMP
Classification: Other
Component: Plugins
2.8.14
Other All
: Normal blocker
: 2.10
Assigned To: GIMP Bugs
GIMP Bugs
CVE-2017-17785
Depends on:
Blocks:
 
 
Reported: 2014-10-24 14:37 UTC by Hanno Böck
Modified: 2017-12-22 15:08 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
sample fli exposing out of bounds write (6.93 KB, video/x-flic)
2014-10-24 14:37 UTC, Hanno Böck
  Details
address sanitizer output (2.21 KB, text/plain)
2014-10-24 14:38 UTC, Hanno Böck
  Details
address sanitizer output decoded / symbolized (2.64 KB, text/plain)
2014-10-24 14:38 UTC, Hanno Böck
  Details
gimp-fli.patch (4.56 KB, patch)
2017-10-29 14:28 UTC, Tobias Stoeckmann
none Details | Review
gimp-fli.patch (4.56 KB, patch)
2017-12-20 18:40 UTC, Tobias Stoeckmann
reviewed Details | Review

Description Hanno Böck 2014-10-24 14:37:17 UTC
I discovered an out-of-bounds write / heap overflow in the fli importer of GIMP.
This can be triggered by the attached sample which has been generated by the zzuf fuzzing tool. It will crash the plugin if gimp has been compiled with -fsanitize=address.
I'll attach the sample and the output of address sanitizer. This may be a security issue if a user opens files from untrusted sources.
Comment 1 Hanno Böck 2014-10-24 14:37:45 UTC
Created attachment 289275 [details]
sample fli exposing out of bounds write
Comment 2 Hanno Böck 2014-10-24 14:38:04 UTC
Created attachment 289276 [details]
address sanitizer output
Comment 3 Hanno Böck 2014-10-24 14:38:29 UTC
Created attachment 289277 [details]
address sanitizer output decoded / symbolized
Comment 4 Mukund Sivaraman 2014-10-27 02:45:51 UTC
Hi Hanno

More than these specific bug reports, I'm very glad to see someone using fuzz testing on the file plug-ins. Please can you mail the gimp-developer list with a HOWTO to test a single file plug-in? I'm sure others will also pick this up.

If you can, can you test the following most frequently used formats:
* XCF
* JPEG
* PNG
* TIFF

If you have more time:
* GIF
* BMP
* PSD
* PDF
* PS
Comment 5 Michael Natterer 2014-11-23 20:08:21 UTC
Hanno, do you plan to write patches for these problems?
Comment 6 Hanno Böck 2014-11-23 22:50:30 UTC
Not really, at least not any time soon. But I'll probably follow the request to post a quick how-to-fuzz-gimp-plugins to your dev list.
Comment 7 Tobias Stoeckmann 2017-10-29 14:28:39 UTC
Created attachment 362488 [details] [review]
gimp-fli.patch

Fixes given test case and more RLE issues in the code.
Comment 8 Michael Natterer 2017-12-19 20:22:02 UTC
I assume the patch was tested on some files? If yes it should simply
be pushed to master.
Comment 9 Raphael Hertzog 2017-12-20 08:46:24 UTC
FYI this security issue has been given the following CVE number: CVE-2017-17785
Comment 10 Jehan 2017-12-20 14:44:42 UTC
Review of attachment 362488 [details] [review]:

I did a review, that looks good.

There is only this line I have been wondering about:

> +       if (numline > fli_header->height || fli_header->height-numline > firstline)
> +               return;

Are you sure about the test, in particular the second part? Maybe I don't understand what firstline and numline are meant to be (in this case, naming is not good), but if I do, I would think that firstline + numline should always be lesser than the height (therefore this test would always return TRUE for a valid file).
Do I misunderstand something?

Also same as Mitch, comment 8, has this been tested with the FLI files running the exploit?

As soon as you clarify my question on the if test and confirm that it has been thoroughly tested, I see no reason why not to push immediately.
Comment 11 Tobias Stoeckmann 2017-12-20 18:39:07 UTC
(In reply to Jehan from comment #10)
> > +       if (numline > fli_header->height || fli_header->height-numline > firstline)
> > +               return;
> 
> Are you sure about the test, in particular the second part?

You are correct, it's supposed to be larger or equal, therefore the test must check the "lesser than" case.
Comment 12 Tobias Stoeckmann 2017-12-20 18:40:08 UTC
Created attachment 365798 [details] [review]
gimp-fli.patch

Updated patch
Comment 13 Jehan 2017-12-21 12:14:29 UTC
Review of attachment 365798 [details] [review]:

Hmmmm…
Sorry to be boring, but:

> +       if (numline > fli_header->height || fli_header->height-numline < firstline)

Shouldn't there be an '=' now?

> +       if (numline > fli_header->height || fli_header->height-numline <= firstline)

I mean if firstline starts at 0 (which I assume it does as it should!), then it should be '<=' because then being at height is already out of bounds!

Also you didn't answer if this has been tested with actual files too. This is an important question. :-)
Comment 14 Tobias Stoeckmann 2017-12-21 19:05:52 UTC
(In reply to Jehan from comment #13)
> Shouldn't there be an '=' now?
> 
> > +       if (numline > fli_header->height || fli_header->height-numline <= firstline)

No, being equal is a good condition. Imagine that height is 1 and firstline is 0. Then numline (the amount of iterations through the for-loop) can be 1, as that's a valid range.

> Also you didn't answer if this has been tested with actual files too. This
> is an important question. :-)

I have no real fli files. I was unable to reproduce the crash/exploit with applied patch, but then again, the initial patch broke the LC implementation as well.
Comment 15 Hanno Böck 2017-12-22 12:07:59 UTC
FLI files: https://samples.ffmpeg.org/fli-flc/

I'll do some tests later.
Comment 16 Jehan 2017-12-22 13:29:32 UTC
> No, being equal is a good condition.

Indeed, you are right.

> I have no real fli files.

I found this link: http://netghost.narod.ru/gff/sample/images/fli/index.htm
I was able to properly open the 2 FLI files available there before and after the patch. And this patch looks good to me after the last review, and it would obviously fix some cases of out-of-bounds memory reading.

Pushed in master:

commit edb251a7ef1602d20a5afcbf23f24afb163de63b (HEAD -> master, origin/master, origin/HEAD)
Author: Tobias Stoeckmann <tobias@stoeckmann.org>
Date:   Sun Oct 29 15:19:41 2017 +0100

    Bug 739133 - (CVE-2017-17785) Heap overflow while parsing FLI files.
    
    It is possible to trigger a heap overflow while parsing FLI files. The
    RLE decoder is vulnerable to out of boundary writes due to lack of
    boundary checks.
    
    The variable "framebuf" points to a memory area which was allocated
    with fli_header->width * fli_header->height bytes. The RLE decoder
    therefore must never write beyond that limit.
    
    If an illegal frame is detected, the parser won't stop, which means
    that the next valid sequence is properly parsed again. This should
    allow GIMP to parse FLI files as good as possible even if they are
    broken by an attacker or by accident.
    
    While at it, I changed the variable xc to be of type size_t, because
    the multiplication of width and height could overflow a 16 bit type.
    
    Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>

In 2.8:

commit 1882bac996a20ab5c15c42b0c5e8f49033a1af54 (HEAD -> gimp-2-8, origin/gimp-2-8)
Author: Tobias Stoeckmann <tobias@stoeckmann.org>
Date:   Sun Oct 29 15:19:41 2017 +0100

    Bug 739133 - (CVE-2017-17785) Heap overflow while parsing FLI files.
    
    It is possible to trigger a heap overflow while parsing FLI files. The
    RLE decoder is vulnerable to out of boundary writes due to lack of
    boundary checks.
    
    The variable "framebuf" points to a memory area which was allocated
    with fli_header->width * fli_header->height bytes. The RLE decoder
    therefore must never write beyond that limit.
    
    If an illegal frame is detected, the parser won't stop, which means
    that the next valid sequence is properly parsed again. This should
    allow GIMP to parse FLI files as good as possible even if they are
    broken by an attacker or by accident.
    
    While at it, I changed the variable xc to be of type size_t, because
    the multiplication of width and height could overflow a 16 bit type.
    
    Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
    (cherry picked from commit edb251a7ef1602d20a5afcbf23f24afb163de63b)

 plug-ins/file-fli/fli.c | 50 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 15 deletions(-)

Thanks for the patches!
Comment 17 Jehan 2017-12-22 15:08:37 UTC
For information: after checking that we had no pending patch related to FLI support (and actually no bug report even, it would seem), I just cleaned up the whole FLI plug-in to follow our coding style.
Previous style was a huge compressed mess which was very hard to read (and a bit suffocating IMO!).

There should be absolutely no code difference before and after (and if there is, that is a mistake from me), only coding style fix (spaces and such). Yet that touches the whole file. So if you were planning to do more stuff on this file, don't forget to push. Working on previous code will likely not merge well. :-)

Of course I tested afterwards with a bunch of FLI files (from the link I gave in comment 16 as well as from the link Hanno gave in comment 15) and it looks I didn't break anything by mistake. :-P