Skip to content

gamut-ifd: nothing bounds the breadth of a sub-IFD pointer array #579

Description

@justin13888

A sub-IFD pointer field is a LONG/LONG8 array, and its element count comes from the file.
gamut_ifd::reader::resolve_pointers_with follows every element, parsing a directory per offset,
with no bound on how many. Depth is bounded (MAX_SUBIFD_DEPTH, 16) and cycles are refused, but
breadth is not — one entry can name as many children as its count field says, and a reader that
accepts N of them does N directory parses plus N membership tests.

Making the visited set a real set (filed separately) removes the quadratic term but not the linear
one: a 20 MB file that is nothing but a pointer array still costs 5M directory parses.

The question this issue is for is what the bound should be, and whether it belongs here at all:

  • a fixed maximum children-per-entry (what value, and from which spec clause — TIFF 6.0 gives
    none, DNG's SubIFDs usage is small, EXIF's Interop is one);
  • a budget over the whole walk (total directories parsed) rather than per entry, which is what a
    hostile tree actually spends;
  • or leaving it to the consumer, since gamut-tiff already carries a decode size cap and the
    offsets must all be in bounds of a file the caller supplied.

Note the interaction with the existing loop guard: every offset must be distinct, so N is already
bounded by the number of distinct in-bounds offsets, i.e. by file length — which is why this is a
cost question rather than a memory-safety one.

Filed from the review of #520.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions