Looks like this vulnerability - at least for the first test case - is because we assume that a tiff will only have one transfer function that is the same for all pages. However, we read the transfer function for every page.
Depending on the transfer function, we allocate either 2 or 4 bytes to the XREF buffer. We allocate this memory after we read in the transfer function for the page. For the first exploit - POC1, this file has 3 pages. For the first page we allocate 2 extra extra XREF entries. Then for the next page 2 more entries. Then for the last page the transfer function changes and we allocate 4 more entries. When we read the file into memory, we assume we have 4 bytes extra for each and every page (as per the last transfer function we read). Which is not correct, we only have 2 bytes extra for the first 2 pages. As a result, we end up writing past the end of the buffer. I haven't yet looked at the other exploits in detail, however I suspect they might be all variations on the same vulnerability. Unfortunately, having trouble finding tiff specifications. At looks like I need to be an Adobe partner to access the specifications at <https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf>. In particular, would like to know if different transfer functions for each page are permitted. Regardless, it seems clear the code doesn't support it. It seems to assume the transfer function will be the same for every page. Also can't find an upstream BTS, is this a project with a dead upstream? http://www.libtiff.org/bugs.html contains dead links. Suggested solutions: * I could allocate 4 bytes for every page, regardless of the transfer function. This wouldn't necessarily give correct results, but would presumably solve the security issue. This is probably the simplist solution. * I could allocate the memory required after it scans all pages, and we know what the final transfer function is. Again, may not necessarily give correct results, but would presumably solve the security issue. Probably not really worth it over the previous solution for a maximum potential savings of 2 bytes per page. * I could alter the code to abort with an error if the transfer function changes to have different (or maybe just increased) memory requirements. -- Brian May <br...@linuxpenguins.xyz> https://linuxpenguins.xyz/brian/