2020.08.28 07:22 "[Tiff] Valgrind reports invalid read when using uint8 RichTiffIPTC tag values in TIFFSetField()", by Agnish Dutta

2020.08.28 07:22 "[Tiff] Valgrind reports invalid read when using uint8 RichTiffIPTC tag values in TIFFSetField()", by Agnish Dutta

Hello team,

I work as a developer at MathWorks and we use libtiff to read/write Tiff files.

We are currently using LIBTIFF, Version 4.1.0.

We noticed some erroneous behavior when trying to use this library to set the "RichTiffIPTC tag. From the following line in the 'tif_dirinfo.c' file,

{ TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL }

It looks like RichTiffIPTC tag values are expected to be in 'long'. As a result when uint8 data is passed to the "TIFFSetField()" function, the data bytes aren't set in the right order and the values get garbled up. This issue was detected by valgrind and lines from the stack trace are as follows:

==6094==    by 0x6BB5F737: _TIFFmemcpy (/3p/derived/glnxa64/tiff/libtiff/tif_unix.c:346)
==6094==    by 0x6BB298B0: _TIFFVSetField (/3p/derived/glnxa64/tiff/libtiff/tif_dir.c:641)
==6094==    by 0x6BB2A0A8: TIFFVSetField (/3p/derived/glnxa64/tiff/libtiff/tif_dir.c:868)
==6094==    by 0x6BB2A134: TIFFSetField (/3p/derived/glnxa64/tiff/libtiff/tif_dir.c:812)

I created a standalone (attached file, main.c) that uses libtiff and ran valgrind on it and I was able to reproduce the invalid reads.

I also found a few references in the libtiff mailing list archives which mention that it'd be more preferable of the tag value could be set to BYTE or UNDEFINED while writing data:

https://www.asmail.be/msg0054616481.html
https://asmail.be/msg0055377345.html

We were wondering if this is a known issue or a workaround to fix these invalid read? Are we not supposed to use BYTE/uint8 values to write 'RichTIFFIPTC' tag in TIFF files. If not, what is the recommended way?

Hope to hear from you soon.

Regards,
Agnish Dutta
Developer, MathWorks.

#include<stdio.h>
#include<stdlib.h>
#include<tiffio.h>
#include<tiff.h>
#define FILENAME "mytest.tif"

int main()
{
TIFF* out = TIFFOpen(FILENAME, "w");
uint8 *richTiffIPTC = (uint8 *)malloc(sizeof(uint8)*12);
for (int i=0; i<12; i++)
{
      richTiffIPTC[i] = (uint8)(i);
}
//{1,2,3,4,5,6,7,8,9,0,11,255};
TIFFSetField(out, TIFFTAG_RICHTIFFIPTC, 12, richTiffIPTC);
TIFFClose(out);
free(richTiffIPTC);
}