Hugo Lefeuvre <h...@debian.org> writes:

> So, after some debugging on CVE-2018-7456, I start to get the feeling to
> understand the issue.
>
> Here are my conclusions for the moment:
>
> * In any case, the transfer function should not care about other
>   channels defined by ExtraSamples (see 2nd and 3rd paragraphs of
>   TransferFunction entry, page 84 of the specification), so something
>   like the following patch should be a first step:
>
> --- a/libtiff/tif_print.c     2018-03-17 21:56:47.000000000 +0100
> +++ b/libtiff/tif_print.c     2018-03-17 22:05:58.446092016 +0100
> @@ -546,7 +546,7 @@
>                               uint16 i;
>                               fprintf(fd, "    %2ld: %5u",
>                                   l, td->td_transferfunction[0][l]);
> -                             for (i = 1; i < td->td_samplesperpixel; i++)
> +                             for (i = 1; i < td->td_samplesperpixel - 
> td->td_extrasamples; i++)
>                                       fprintf(fd, " %5u",
>                                           td->td_transferfunction[i][l]);
>                               fputc('\n', fd);
>
> But it's not enough. Why ?
>
> * I discovered that td->td_samplesperpixel can have arbitrary size while
>   td->td_extrasamples stays 0. It shouldn't be the case ! For instance
>   the specification doesn't allow RGB with 4 channels and no ExtraSamples.
>   And while it doesn't make any sense, libtiff won't notice it.
>
>   I even tried RGB with 8 channels and no ExtraSamples and it worked too.
>
>   So, what should be done ?
>
>   For each PhotometricInterpretation type there is a 'standard' samples
>   per pixel value (that is the samples per pixel value without extra samples:
>   3 for RGB, etc). Let's name it (standard spp).
>
>   So, what we should do is: If the actual td->td_samplesperpixel is higher
>   than (standard spp), then we should assume that td->td_extrasamples is
>   td->td_samplesperpixel - (standard spp), even if no ExtraSamples field
>   was specified OR if the specified td->td_extrasamples was smaller.

Seems good to me. I would suggest sending a patch upstream, see what
they think.

Also I tend to think some some of assertion might be a good idea,
something that aborts if

(td->td_samplesperpixel - td->td_extrasamples) > 3

As aborting early is probably better then screwing up memory.


For reference, the next value in the struct is:

typedef struct {
        [...]

        /* Colorimetry parameters */
        uint16* td_transferfunction[3];
        float*  td_refblackwhite;

        [...]
} TIFFDirectory;

So I am guessing when you access td_transferfunction[3], you are
actually accessing td_refblackwhite, which - surprise surprise - happens
to be NULL.
-- 
Brian May <b...@debian.org>

Reply via email to