[go: up one dir, main page]

Bug 2772 - Uncontrolled resource consumption in TIFFSetDirectory (src/libtiff/tif_dir.c) (CVE-2018-5784)
: Uncontrolled resource consumption in TIFFSetDirectory (src/libtiff/tif_dir.c)...
Status: RESOLVED FIXED
: libtiff
default
: unspecified
: PC Linux
: P2 normal
: ---
Assigned To:
:
:
:
:
:
  Show dependency treegraph
 
Reported: 2018-01-18 16:38 by
Modified: 2018-02-14 11:04 (History)


Attachments
poc for libtiff (307 bytes, image/tiff)
2018-01-18 16:38, Wei You
Details


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2018-01-18 16:38:16
Created an attachment (id=840) [details]
poc for libtiff

On latest version (4.0.9) and master branch of libtiff:
there is an uncontrolled resource consumption in TIFFSetDirectory function of
src/libtiff/tif_dir.c, which can cause denial of service through a crafted tif
file.

The problem happens since in "for" loop (line 1608), the TIFFAdvanceDirectory
continuously assigns a same value to "nextdir" until n <= 0. The terminating
condition could be manipulated by the attached POC file (although its size is
only 300 bytes). 

Note that in the POC file, it declares that there are 65535 directories. But
actually the POC contains only one directory entry. However, still the libtiff
enumerates the same entry for 65535 times.

Suggestion fix: add a check to determine whether the actual number of directory
entries contained in the file equals the declared value.

In src/libtiff/tif_dir.c 

   1599 TIFFSetDirectory(TIFF* tif, uint16 dirn)
   1600 {
   ...
   1608         for (n = dirn; n > 0 && nextdir != 0; n--)
   1609                 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
   1610                         return (0);

To reproduce the issue, run: tiff2pdf $POC -o OUTPUT
------- Comment #1 From 2018-01-18 16:40:29 -------
(In reply to comment #0)

Note that this issue exists in the libtiff library code. Applications using
libtiff library are affected.

> Created an attachment (id=840) [details] [details]
> poc for libtiff
> 
> On latest version (4.0.9) and master branch of libtiff:
> there is an uncontrolled resource consumption in TIFFSetDirectory function of
> src/libtiff/tif_dir.c, which can cause denial of service through a crafted tif
> file.
> 
> The problem happens since in "for" loop (line 1608), the TIFFAdvanceDirectory
> continuously assigns a same value to "nextdir" until n <= 0. The terminating
> condition could be manipulated by the attached POC file (although its size is
> only 300 bytes). 
> 
> Note that in the POC file, it declares that there are 65535 directories. But
> actually the POC contains only one directory entry. However, still the libtiff
> enumerates the same entry for 65535 times.
> 
> Suggestion fix: add a check to determine whether the actual number of directory
> entries contained in the file equals the declared value.
> 
> In src/libtiff/tif_dir.c 
> 
>    1599 TIFFSetDirectory(TIFF* tif, uint16 dirn)
>    1600 {
>    ...
>    1608         for (n = dirn; n > 0 && nextdir != 0; n--)
>    1609                 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
>    1610                         return (0);
> 
> To reproduce the issue, run: tiff2pdf $POC -o OUTPUT
------- Comment #2 From 2018-01-19 04:27:43 -------
This issue was assigned CVE-2018-5784
------- Comment #3 From 2018-02-05 17:17:18 -------
I don't believe the problem is described entirely correctly in the bug report.
The problem isn't the number of directories reported by the POC file (the bug
report is incorrect; the POC file only reports 18 directories and also contains
18 directories). The problem is that after the 18 directories are read from the
IFD, the offset of the next IFD is given as the head of the current IFD. 

This back pointer essentially creates a circular linked list of IFDs and
therefore  causes libtiff to continue reading directories until it hits its
hard-coded maximum of 65535, at which point it carries on processing.

There are a couple of remediations:
1. Don't allow back pointers to previous IFDs. I don't know enough about the
TIFF file format to know if this is a valid fix.
2. Perform a pre-check of the file before processing it to ensure there are no
loops.
3. Reject any TIFF document which contains more than 65535 directories.

I beleive it is possible to craft a valid TIFF document with no IFD loops which
would be rejected by remediation 1, though remediation 1 is also the easiest.

Remediation 2 would be the most complete solution, but for extremely large TIFF
documents it could dramatically increase the processing time and resource
usage.

Remediation 3 could result in false positives, but is the least intrusive.
Simple, naive benchmarking suggests that it's possible to process and reject
the proof of concept TIFF document in under a second, which remediates the
denial of service.
------- Comment #5 From 2018-02-14 11:04:45 -------
Thanks for the fix.

(In reply to comment #4)
> Fixed per
> https://gitlab.com/libtiff/libtiff/commit/473851d211cf8805a161820337ca74cc9615d6ef