diff -Nru jhead-3.00/debian/changelog jhead-3.00/debian/changelog --- jhead-3.00/debian/changelog 2019-01-29 15:06:57.000000000 +0000 +++ jhead-3.00/debian/changelog 2023-05-16 08:57:25.000000000 +0000 @@ -1,3 +1,42 @@ +jhead (1:3.00-8~ubuntu0.1) bionic-security; urgency=medium + + * SECURITY UPDATE: heap out-of-bounds read when processing the JFIF markers + - debian/patches/CVE-2019-19035.patch: Adds verifications in jpgfile.c. The + number of sections should be greater than 7. The JFIF header should exist + before verifying its magic bytes. + - CVE-2019-19035 + * SECURITY UPDATE: stack buffer overflow when processing longitude tags + - debian/patches/CVE-2019-1010301.patch: Replaces a call to sprintf with + one to snprinf in gpsinfo.c. + - CVE-2019-1010301 + * SECURITY UPDATE: heap buffer overflow when processing IPTC data + - debian/patches/CVE-2019-1010302.patch: Ensures the length of IPTC data is + strictly positive in iptc.c. + - CVE-2019-1010302 + * SECURITY UPDATE: heap buffer overflow when processing the DQT markers + - debian/patches/CVE-2020-6624.patch: Adds further DQT verifications in + jpgqguess.c. + - CVE-2020-6624 + * SECURITY UPDATE: heap out-of-bounds read when processing longitude tags + - debian/patches/CVE-2020-6625.patch: Adds further verifications in + gpsinfo.c. + - CVE-2020-6625 + * SECURITY UPDATE: heap buffer overflow when reading JPEG sections + - debian/patches/CVE-2020-26208.patch: Allocates additional 20 bytes in + jpgfile.c. + - CVE-2020-26208 + * SECURITY UPDATE: heap out-of-bounds read when processing Canon images + - debian/patches/CVE-2021-28276_28278.patch: Adds further verifications in + makernote.c. + - CVE-2021-28276 + * SECURITY UPDATE: heap buffer overflow when removing a certain type of + section + - debian/patches/CVE-2021-28276_28278.patch: Adds further verifications + while processing nested EXIF directories in exif.c. + - CVE-2021-28278 + + -- George-Andrei Iosif Tue, 16 May 2023 11:57:25 +0300 + jhead (1:3.00-8~build0.18.04.1) bionic-security; urgency=medium * fake sync from Debian diff -Nru jhead-3.00/debian/control jhead-3.00/debian/control --- jhead-3.00/debian/control 2018-09-19 17:55:26.000000000 +0000 +++ jhead-3.00/debian/control 2023-05-16 08:57:25.000000000 +0000 @@ -1,7 +1,8 @@ Source: jhead Section: graphics Priority: optional -Maintainer: Ludovic Rousseau +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Ludovic Rousseau Build-Depends: debhelper (>> 11) Standards-Version: 4.2.1 Vcs-Git: https://salsa.debian.org/debian/jhead.git diff -Nru jhead-3.00/debian/patches/CVE-2019-1010301.patch jhead-3.00/debian/patches/CVE-2019-1010301.patch --- jhead-3.00/debian/patches/CVE-2019-1010301.patch 1970-01-01 00:00:00.000000000 +0000 +++ jhead-3.00/debian/patches/CVE-2019-1010301.patch 2023-05-16 08:57:25.000000000 +0000 @@ -0,0 +1,19 @@ +From: Ludovic Rousseau +Date: Fri Aug 2 17:36:39 CEST 2019 +Subject: use snprintf() instead of sprintf() +Bug-Debian: http://bugs.debian.org/932145 +Description: Fix CVE-2019-1010301 +Backport of: 2e2726a14d9608d4ff4fdd2130a15e999ca70d79 +Index: jhead-3.00/gpsinfo.c +=================================================================== +--- jhead-3.00.orig/gpsinfo.c ++++ jhead-3.00/gpsinfo.c +@@ -148,7 +148,7 @@ void ProcessGpsInfo(unsigned char * DirS + Values[a] = ConvertAnyFormat(ValuePtr+a*ComponentSize, Format); + } + +- sprintf(TempString, FmtString, Values[0], Values[1], Values[2]); ++ snprintf(TempString, sizeof TempString, FmtString, Values[0], Values[1], Values[2]); + + if (Tag == TAG_GPS_LAT){ + strncpy(ImageInfo.GpsLat+2, TempString, 29); diff -Nru jhead-3.00/debian/patches/CVE-2019-1010302.patch jhead-3.00/debian/patches/CVE-2019-1010302.patch --- jhead-3.00/debian/patches/CVE-2019-1010302.patch 1970-01-01 00:00:00.000000000 +0000 +++ jhead-3.00/debian/patches/CVE-2019-1010302.patch 2023-05-16 08:57:25.000000000 +0000 @@ -0,0 +1,20 @@ +From: Ludovic Rousseau +Date: Fri Aug 2 18:20:39 CEST 2019 +Subject: check length is strictly positive +Bug-Debian: http://bugs.debian.org/932146 +Description: Fix CVE-2019-1010302 +Backport of: 2e2726a14d9608d4ff4fdd2130a15e999ca70d79 + +Index: jhead-3.00/iptc.c +=================================================================== +--- jhead-3.00.orig/iptc.c ++++ jhead-3.00/iptc.c +@@ -126,6 +126,8 @@ void show_IPTC (unsigned char* Data, uns + + type = *pos++; + length = (*pos << 8) + (*(pos+1)); ++ if (length < 1) ++ goto corrupt; + pos += 2; // Skip tag length + + if (pos+length > maxpos) goto corrupt; diff -Nru jhead-3.00/debian/patches/CVE-2019-19035.patch jhead-3.00/debian/patches/CVE-2019-19035.patch --- jhead-3.00/debian/patches/CVE-2019-19035.patch 1970-01-01 00:00:00.000000000 +0000 +++ jhead-3.00/debian/patches/CVE-2019-19035.patch 2023-05-16 08:53:51.000000000 +0000 @@ -0,0 +1,44 @@ +From 742f36e618719a39a852f89b0d3c68aac1482b67 Mon Sep 17 00:00:00 2001 +From: Ludovic Rousseau +Date: Fri, 22 Nov 2019 17:41:30 +0100 +Subject: 1:3.04-1 (patches unapplied) + +Imported using git-ubuntu import. +--- + jpgfile.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +(limited to 'jpgfile.c') + +Index: jhead-3.00/jpgfile.c +=================================================================== +--- jhead-3.00.orig/jpgfile.c ++++ jhead-3.00/jpgfile.c +@@ -248,13 +248,13 @@ int ReadJpegSections (FILE * infile, Rea + // marker instead, althogh ACDsee will write images with both markers. + // this program will re-create this marker on absence of exif marker. + // hence no need to keep the copy from the file. +- if (memcmp(Data+2, "JFIF\0",5)){ +- fprintf(stderr,"Header missing JFIF marker\n"); +- } + if (itemlen < 16){ + fprintf(stderr,"Jfif header too short\n"); + goto ignore; + } ++ if (memcmp(Data+2, "JFIF\0",5)){ ++ fprintf(stderr,"Header missing JFIF marker\n"); ++ } + + ImageInfo.JfifHeader.Present = TRUE; + ImageInfo.JfifHeader.ResolutionUnits = Data[9]; +@@ -326,6 +326,10 @@ int ReadJpegSections (FILE * infile, Rea + case M_SOF13: + case M_SOF14: + case M_SOF15: ++ if (itemlen < 8){ ++ fprintf(stderr,"Section too short\n"); ++ break; ++ } + process_SOFn(Data, marker); + break; + default: diff -Nru jhead-3.00/debian/patches/CVE-2020-26208.patch jhead-3.00/debian/patches/CVE-2020-26208.patch --- jhead-3.00/debian/patches/CVE-2020-26208.patch 1970-01-01 00:00:00.000000000 +0000 +++ jhead-3.00/debian/patches/CVE-2020-26208.patch 2023-05-16 08:57:25.000000000 +0000 @@ -0,0 +1,36 @@ +From 5186ddcf9e35a7aa0ff0539489a930434a1325f4 Mon Sep 17 00:00:00 2001 +From: Matthias +Date: Fri, 23 Oct 2020 10:17:20 -0300 +Subject: [PATCH] Just allocate 20 bytes extra at the end of a section. + Otherwise, we end up with a whole lot of little checks for structures that + the file says are there but are unexpectedly cut off in fuzz tests + +--- + jpgfile.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +Index: jhead-3.00/jpgfile.c +=================================================================== +--- jhead-3.00.orig/jpgfile.c ++++ jhead-3.00/jpgfile.c +@@ -170,7 +170,10 @@ int ReadJpegSections (FILE * infile, Rea + + Sections[SectionsRead].Size = itemlen; + +- Data = (uchar *)malloc(itemlen); ++ // Allocate an extra 20 bytes more than needed, because sometimes when reading structures, ++ // if the section erroneously ends before short structures that should be there, that can trip ++ // memory checkers in combination with fuzzers. ++ Data = (uchar *)malloc(itemlen+20); + if (Data == NULL){ + ErrFatal("Could not allocate memory"); + } +@@ -476,7 +479,7 @@ int ReplaceThumbnail(const char * ThumbF + return FALSE; + } + +- ThumbLen = 0; ++ ThumbLen = 0; + ThumbnailFile = NULL; + } + diff -Nru jhead-3.00/debian/patches/CVE-2020-6624.patch jhead-3.00/debian/patches/CVE-2020-6624.patch --- jhead-3.00/debian/patches/CVE-2020-6624.patch 1970-01-01 00:00:00.000000000 +0000 +++ jhead-3.00/debian/patches/CVE-2020-6624.patch 2023-05-16 08:57:25.000000000 +0000 @@ -0,0 +1,80 @@ +From 7c92f0a5ca418fda5881288a5fcf90fd3618e06e Mon Sep 17 00:00:00 2001 +From: Joachim Reichel +Date: Sun, 30 May 2021 14:21:52 +0200 +Subject: 1:3.06.0.1-1 (patches unapplied) + +Imported using git-ubuntu import. +--- + jpgqguess.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +(limited to 'jpgqguess.c') + +Index: jhead-3.00/jpgqguess.c +=================================================================== +--- jhead-3.00.orig/jpgqguess.c ++++ jhead-3.00/jpgqguess.c +@@ -89,8 +89,9 @@ static int jpeg_zigzag_order[64] = { + int allones = 1; + + a=2; // first two bytes is length +- while (a length) goto tooshort; + c = Data[a++]; + tableindex = c & 0x0f; + if (ShowTags>1){ +@@ -99,12 +100,16 @@ static int jpeg_zigzag_order[64] = { + if (tableindex < 2){ + reftable = deftabs[tableindex]; + } +- + // Read in the table, compute statistics relative to reference table ++ if (c>>4 && a+128 > length) { ++tooshort: ++ ErrNonfatal("DQT section too short",0,0); ++ return; ++ } + for (coefindex = 0; coefindex < 64; coefindex++) { + unsigned int val; + if (c>>4) { +- register unsigned int temp; ++ unsigned int temp; + temp=(unsigned int) (Data[a++]); + temp *= 256; + val=(unsigned int) Data[a++] + temp; +@@ -172,10 +177,10 @@ void process_DHT (const uchar * Data, in + int a, i; + int c, c2; + unsigned char huff[16]; +- + if (ShowTags>1){ + printf("DHT (length %d bytes)\n", length); + } ++ if (length < 19) goto tooshort; + + a=2; // first two bytes is length + while (a1){ + printf(" table %d\n", c); + } ++ if (a+16 > length){ ++ tooshort: ++ ErrFatal("Huff table too short"); ++ } ++ + for (i=0; i<16; i++) { + huff[i]=(unsigned char) Data[a++]; + } +@@ -191,6 +201,9 @@ void process_DHT (const uchar * Data, in + if (ShowTags>2){ + printf(" bits %2d (codes=%3u) ", i+1, (unsigned int) huff[i]); + } ++ if (a+huff[i] > length){ ++ goto tooshort; ++ } + while (huff[i]--) { + c2 = Data[a++]; + if (ShowTags>2){ diff -Nru jhead-3.00/debian/patches/CVE-2020-6625.patch jhead-3.00/debian/patches/CVE-2020-6625.patch --- jhead-3.00/debian/patches/CVE-2020-6625.patch 1970-01-01 00:00:00.000000000 +0000 +++ jhead-3.00/debian/patches/CVE-2020-6625.patch 2023-05-16 08:57:25.000000000 +0000 @@ -0,0 +1,40 @@ +From 7c92f0a5ca418fda5881288a5fcf90fd3618e06e Mon Sep 17 00:00:00 2001 +From: Joachim Reichel +Date: Sun, 30 May 2021 14:21:52 +0200 +Subject: 1:3.06.0.1-1 (patches unapplied) + +Index: jhead-3.00/gpsinfo.c +=================================================================== +--- jhead-3.00.orig/gpsinfo.c ++++ jhead-3.00/gpsinfo.c +@@ -89,6 +89,12 @@ void ProcessGpsInfo(unsigned char * DirS + Format = Get16u(DirEntry+2); + Components = Get32u(DirEntry+4); + ++ if (Components > 0x10000){ ++ //Components count too large could cause overflow on subsequent check ++ ErrNonfatal("Bad components count %x", Components,0); ++ continue; ++ } ++ + if ((Format-1) >= NUM_FORMATS) { + // (-1) catches illegal zero case as unsigned underflows to positive large. + ErrNonfatal("Illegal number format %d for Exif gps tag %04x", Format, Tag); +@@ -102,7 +108,7 @@ void ProcessGpsInfo(unsigned char * DirS + unsigned OffsetVal; + OffsetVal = Get32u(DirEntry+8); + // If its bigger than 4 bytes, the dir entry contains an offset. +- if (OffsetVal > UINT32_MAX - ByteCount || OffsetVal+ByteCount > ExifLength){ ++ if (OffsetVal+ByteCount > ExifLength || OffsetVal > 65536){ + // Bogus pointer offset and / or bytecount value + ErrNonfatal("Illegal value pointer for Exif gps tag %04x", Tag,0); + continue; +@@ -146,7 +152,7 @@ void ProcessGpsInfo(unsigned char * DirS + FmtString[3+a*7] = (char)('0'+digits); + + Values[a] = ConvertAnyFormat(ValuePtr+a*ComponentSize, Format); +- } ++ } + + snprintf(TempString, sizeof TempString, FmtString, Values[0], Values[1], Values[2]); + diff -Nru jhead-3.00/debian/patches/CVE-2021-28276_28278.patch jhead-3.00/debian/patches/CVE-2021-28276_28278.patch --- jhead-3.00/debian/patches/CVE-2021-28276_28278.patch 1970-01-01 00:00:00.000000000 +0000 +++ jhead-3.00/debian/patches/CVE-2021-28276_28278.patch 2023-05-16 08:57:25.000000000 +0000 @@ -0,0 +1,90 @@ +From a50953a266583981b51a181c2fce73dad2ac5d7d Mon Sep 17 00:00:00 2001 +From: matthias wandel +Date: Thu, 4 Mar 2021 12:18:27 -0400 +Subject: [PATCH] Make pointer range checks more consistent. Also twiddle + the unused floating point print code (not used in real exif files), but + fuzz testing hits it. New code is equivalent but doesn't cause bus error + (don't understand why, but this is all a very bogus thing anyway, just trying + to avoid fuzz testing hits. + +--- + exif.c | 32 ++++++++++++++++++++++++++------ + gpsinfo.c | 2 +- + makernote.c | 2 +- + 3 files changed, 28 insertions(+), 8 deletions(-) + +Index: jhead-3.00/exif.c +=================================================================== +--- jhead-3.00.orig/exif.c ++++ jhead-3.00/exif.c +@@ -390,7 +390,15 @@ void PrintFormatNumber(void * ValuePtr, + s = 8; + break; + +- case FMT_SINGLE: printf("%f",(double)*(float *)ValuePtr); s=8; break; ++ case FMT_SINGLE: ++ { ++ float f; ++ int tmp = *(int*)ValuePtr; ++ f = *(float *)&tmp; ++ printf("%f",f); ++ } ++ s=4; ++ break; + case FMT_DOUBLE: printf("%f",*(double *)ValuePtr); s=8; break; + default: + printf("Unknown format %d:", Format); +@@ -442,9 +450,20 @@ double ConvertAnyFormat(void * ValuePtr, + case FMT_SSHORT: Value = (signed short)Get16u(ValuePtr); break; + case FMT_SLONG: Value = Get32s(ValuePtr); break; + +- // Not sure if this is correct (never seen float used in Exif format) +- case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break; +- case FMT_DOUBLE: Value = *(double *)ValuePtr; break; ++ // Never seen floats used in actual exif format, ++ // this code only ever hit with fuzz testing. ++ // This code may not necessaryly print correct values if float *were* ++ // to be used in exif, as it doesn't define which floating point ++ // stanard is to be used. ++ case FMT_SINGLE: ++ { ++ int tmp = *(int*)ValuePtr; ++ Value = *(float *)&tmp; ++ } ++ break; ++ ++ case FMT_DOUBLE: ++ Value = *(double *)ValuePtr; break; + + default: + ErrNonfatal("Illegal format code %d in Exif header",Format,0); +@@ -528,7 +547,7 @@ static void ProcessExifDir(unsigned char + unsigned OffsetVal; + OffsetVal = Get32u(DirEntry+8); + // If its bigger than 4 bytes, the dir entry contains an offset. +- if (OffsetVal > UINT32_MAX - ByteCount || OffsetVal+ByteCount > ExifLength){ ++ if (OffsetVal+ByteCount > ExifLength || OffsetVal > 65536){ + // Bogus pointer offset and / or bytecount value + ErrNonfatal("Illegal value pointer for tag %04x in Exif", Tag,0); + continue; +@@ -987,6 +1006,7 @@ void process_EXIF (unsigned char * ExifS + ExifImageWidth = 0; + NumOrientations = 0; + ++ + if (ShowTags){ + printf("Exif header %u bytes long\n",length); + } +Index: jhead-3.00/makernote.c +=================================================================== +--- jhead-3.00.orig/makernote.c ++++ jhead-3.00/makernote.c +@@ -64,7 +64,7 @@ static void ProcessCanonMakerNoteDir(uns + unsigned OffsetVal; + OffsetVal = Get32u(DirEntry+8); + // If its bigger than 4 bytes, the dir entry contains an offset. +- if (OffsetVal+ByteCount > ExifLength){ ++ if (OffsetVal+ByteCount > ExifLength || OffsetVal > 65536){ + // Bogus pointer offset and / or bytecount value + ErrNonfatal("Illegal value pointer for Exif maker tag %04x", Tag,0); + continue; diff -Nru jhead-3.00/debian/patches/series jhead-3.00/debian/patches/series --- jhead-3.00/debian/patches/series 2018-09-19 17:55:26.000000000 +0000 +++ jhead-3.00/debian/patches/series 2023-05-16 08:57:25.000000000 +0000 @@ -10,3 +10,10 @@ 33_fix_908176 34_buffer_overflow 35_fix_alloc_size +CVE-2019-19035.patch +CVE-2019-1010301.patch +CVE-2019-1010302.patch +CVE-2020-6624.patch +CVE-2020-6625.patch +CVE-2020-26208.patch +CVE-2021-28276_28278.patch