[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: tiff / CVE-2018-7456



Hugo Lefeuvre <hle@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 <bam@debian.org>


Reply to: