You need to log in before you can comment on or make changes to this bug.
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
(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
This issue was assigned CVE-2018-5784
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.
Fixed per https://gitlab.com/libtiff/libtiff/commit/473851d211cf8805a161820337ca74cc9615d6ef
Thanks for the fix. (In reply to comment #4) > Fixed per > https://gitlab.com/libtiff/libtiff/commit/473851d211cf8805a161820337ca74cc9615d6ef