!79 fix CVE-2022-1622 CVE-2022-16223
From: @wcc_140409 Reviewed-by: @t_feng Signed-off-by: @t_feng
This commit is contained in:
commit
374ff1c4e0
772
backport-0001-CVE-2022-1622-CVE-2022-1623.patch
Normal file
772
backport-0001-CVE-2022-1622-CVE-2022-1623.patch
Normal file
@ -0,0 +1,772 @@
|
||||
From 189d65779275132c86abd1e06cdab8a080645b32 Mon Sep 17 00:00:00 2001
|
||||
From: Even Rouault <even.rouault@spatialys.com>
|
||||
Date: Thu, 10 Mar 2022 12:14:31 +0100
|
||||
Subject: [PATCH 1/3] tif_lzw.c: make LZW_CHECKEOS non-optional
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/libtiff/libtiff/-/merge_requests/318/diffs
|
||||
|
||||
this is pre-patch for CVE-2022-1622 and CVE-2022-1623
|
||||
---
|
||||
libtiff/tif_lzw.c | 551 ++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 356 insertions(+), 195 deletions(-)
|
||||
|
||||
diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c
|
||||
index c06aec4..c28366b 100644
|
||||
--- a/libtiff/tif_lzw.c
|
||||
+++ b/libtiff/tif_lzw.c
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
+ * Copyright (c) 2022 Even Rouault
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
@@ -36,8 +37,13 @@
|
||||
*/
|
||||
#include "tif_predict.h"
|
||||
|
||||
+#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
+/* Select the plausible largest natural integer type for the architecture */
|
||||
+#define SIZEOF_WORDTYPE SIZEOF_SIZE_T
|
||||
+typedef size_t WordType;
|
||||
+
|
||||
/*
|
||||
* NB: The 5.0 spec describes a different algorithm than Aldus
|
||||
* implements. Specifically, Aldus does code length transitions
|
||||
@@ -52,13 +58,6 @@
|
||||
* Future revisions to the TIFF spec are expected to "clarify this issue".
|
||||
*/
|
||||
#define LZW_COMPAT /* include backwards compatibility code */
|
||||
-/*
|
||||
- * Each strip of data is supposed to be terminated by a CODE_EOI.
|
||||
- * If the following #define is included, the decoder will also
|
||||
- * check for end-of-strip w/o seeing this code. This makes the
|
||||
- * library more robust, but also slower.
|
||||
- */
|
||||
-#define LZW_CHECKEOS /* include checks for strips w/o EOI code */
|
||||
|
||||
#define MAXCODE(n) ((1L<<(n))-1)
|
||||
/*
|
||||
@@ -92,7 +91,7 @@ typedef struct {
|
||||
unsigned short nbits; /* # of bits/code */
|
||||
unsigned short maxcode; /* maximum code for lzw_nbits */
|
||||
unsigned short free_ent; /* next free entry in hash table */
|
||||
- unsigned long nextdata; /* next bits of i/o */
|
||||
+ WordType nextdata; /* next bits of i/o */
|
||||
long nextbits; /* # of valid bits in lzw_nextdata */
|
||||
|
||||
int rw_mode; /* preserve rw_mode from init */
|
||||
@@ -119,8 +118,10 @@ typedef struct {
|
||||
typedef struct code_ent {
|
||||
struct code_ent *next;
|
||||
unsigned short length; /* string len, including this token */
|
||||
- unsigned char value; /* data value */
|
||||
+ /* firstchar should be placed immediately before value in this structure */
|
||||
unsigned char firstchar; /* first token of string */
|
||||
+ unsigned char value; /* data value */
|
||||
+ bool repeated;
|
||||
} code_t;
|
||||
|
||||
typedef int (*decodeFunc)(TIFF*, uint8_t*, tmsize_t, uint16_t);
|
||||
@@ -131,10 +132,8 @@ typedef struct {
|
||||
/* Decoding specific data */
|
||||
long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */
|
||||
long dec_restart; /* restart count */
|
||||
-#ifdef LZW_CHECKEOS
|
||||
uint64_t dec_bitsleft; /* available bits in raw data */
|
||||
tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous TIFLZWDecode() call */
|
||||
-#endif
|
||||
decodeFunc dec_decode; /* regular or backwards compatible */
|
||||
code_t* dec_codep; /* current recognized code */
|
||||
code_t* dec_oldcodep; /* previously recognized code */
|
||||
@@ -167,26 +166,6 @@ static void cl_hash(LZWCodecState*);
|
||||
* LZW Decoder.
|
||||
*/
|
||||
|
||||
-#ifdef LZW_CHECKEOS
|
||||
-/*
|
||||
- * This check shouldn't be necessary because each
|
||||
- * strip is suppose to be terminated with CODE_EOI.
|
||||
- */
|
||||
-#define NextCode(_tif, _sp, _bp, _code, _get) { \
|
||||
- if ((_sp)->dec_bitsleft < (uint64_t)nbits) { \
|
||||
- TIFFWarningExt(_tif->tif_clientdata, module, \
|
||||
- "LZWDecode: Strip %"PRIu32" not terminated with EOI code", \
|
||||
- _tif->tif_curstrip); \
|
||||
- _code = CODE_EOI; \
|
||||
- } else { \
|
||||
- _get(_sp,_bp,_code); \
|
||||
- (_sp)->dec_bitsleft -= nbits; \
|
||||
- } \
|
||||
-}
|
||||
-#else
|
||||
-#define NextCode(tif, sp, bp, code, get) get(sp, bp, code)
|
||||
-#endif
|
||||
-
|
||||
static int
|
||||
LZWFixupTags(TIFF* tif)
|
||||
{
|
||||
@@ -236,17 +215,17 @@ LZWSetupDecode(TIFF* tif)
|
||||
*/
|
||||
code = 255;
|
||||
do {
|
||||
- sp->dec_codetab[code].value = (unsigned char)code;
|
||||
sp->dec_codetab[code].firstchar = (unsigned char)code;
|
||||
+ sp->dec_codetab[code].value = (unsigned char)code;
|
||||
+ sp->dec_codetab[code].repeated = true;
|
||||
sp->dec_codetab[code].length = 1;
|
||||
sp->dec_codetab[code].next = NULL;
|
||||
} while (code--);
|
||||
/*
|
||||
- * Zero-out the unused entries
|
||||
- */
|
||||
- /* Silence false positive */
|
||||
- /* coverity[overrun-buffer-arg] */
|
||||
- _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
|
||||
+ * Zero-out the unused entries */
|
||||
+ /* Silence false positive */
|
||||
+ /* coverity[overrun-buffer-arg] */
|
||||
+ memset(&sp->dec_codetab[CODE_CLEAR], 0,
|
||||
(CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
|
||||
}
|
||||
return (1);
|
||||
@@ -316,11 +295,9 @@ LZWPreDecode(TIFF* tif, uint16_t s)
|
||||
|
||||
sp->dec_restart = 0;
|
||||
sp->dec_nbitsmask = MAXCODE(BITS_MIN);
|
||||
-#ifdef LZW_CHECKEOS
|
||||
sp->dec_bitsleft = 0;
|
||||
- sp->old_tif_rawcc = 0;
|
||||
-#endif
|
||||
- sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
|
||||
+ sp->old_tif_rawcc = 0;
|
||||
+ sp->dec_free_entp = sp->dec_codetab - 1 ; // + CODE_FIRST;
|
||||
/*
|
||||
* Zero entries that are not yet filled in. We do
|
||||
* this to guard against bogus input data that causes
|
||||
@@ -328,8 +305,7 @@ LZWPreDecode(TIFF* tif, uint16_t s)
|
||||
* come up with a way to safely bounds-check input codes
|
||||
* while decoding then you can remove this operation.
|
||||
*/
|
||||
- _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
|
||||
- sp->dec_oldcodep = &sp->dec_codetab[-1];
|
||||
+ sp->dec_oldcodep = &sp->dec_codetab[0];
|
||||
sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];
|
||||
return (1);
|
||||
}
|
||||
@@ -337,24 +313,77 @@ LZWPreDecode(TIFF* tif, uint16_t s)
|
||||
/*
|
||||
* Decode a "hunk of data".
|
||||
*/
|
||||
-#define GetNextCode(sp, bp, code) { \
|
||||
- nextdata = (nextdata<<8) | *(bp)++; \
|
||||
- nextbits += 8; \
|
||||
- if (nextbits < nbits) { \
|
||||
- nextdata = (nextdata<<8) | *(bp)++; \
|
||||
- nextbits += 8; \
|
||||
- } \
|
||||
- code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \
|
||||
- nextbits -= nbits; \
|
||||
-}
|
||||
+/* Get the next 32 or 64-bit from the input data */
|
||||
+
|
||||
+#ifdef WORDS_BIGENDIAN
|
||||
+# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata))
|
||||
+#elif SIZEOF_WORDTYPE == 8
|
||||
+# if defined(__GNUC__) && defined(__x86_64__)
|
||||
+# define GetNextData(nextdata, bp) nextdata = __builtin_bswap64(*(uint64_t*)(bp))
|
||||
+# elif defined(_M_X64)
|
||||
+# define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t*)(bp))
|
||||
+# elif defined(__GNUC__)
|
||||
+# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \
|
||||
+ nextdata = __builtin_bswap64(nextdata)
|
||||
+# else
|
||||
+# define GetNextData(nextdata, bp) nextdata = (((uint64_t)bp[0]) << 56) | \
|
||||
+ (((uint64_t)bp[1]) << 48) | \
|
||||
+ (((uint64_t)bp[2]) << 40) | \
|
||||
+ (((uint64_t)bp[3]) << 32) | \
|
||||
+ (((uint64_t)bp[4]) << 24) | \
|
||||
+ (((uint64_t)bp[5]) << 16) | \
|
||||
+ (((uint64_t)bp[6]) << 8) | \
|
||||
+ (((uint64_t)bp[7]))
|
||||
+# endif
|
||||
+#elif SIZEOF_WORDTYPE == 4
|
||||
+# if defined(__GNUC__) && defined(__i386__)
|
||||
+# define GetNextData(nextdata, bp) nextdata = __builtin_bswap32(*(uint32_t*)(bp))
|
||||
+# elif defined(_M_X86)
|
||||
+# define GetNextData(nextdata, bp) nextdata = _byteswap_ulong(*(unsigned long*)(bp))
|
||||
+# elif defined(__GNUC__)
|
||||
+# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \
|
||||
+ nextdata = __builtin_bswap32(nextdata)
|
||||
+# else
|
||||
+# define GetNextData(nextdata, bp) nextdata = (((uint32_t)bp[0]) << 24) | \
|
||||
+ (((uint32_t)bp[1]) << 16) | \
|
||||
+ (((uint32_t)bp[2]) << 8) | \
|
||||
+ (((uint32_t)bp[3]))
|
||||
+# endif
|
||||
+#else
|
||||
+# error "Unhandled SIZEOF_WORDTYPE"
|
||||
+#endif
|
||||
|
||||
-static void
|
||||
-codeLoop(TIFF* tif, const char* module)
|
||||
-{
|
||||
- TIFFErrorExt(tif->tif_clientdata, module,
|
||||
- "Bogus encoding, loop in the code table; scanline %"PRIu32,
|
||||
- tif->tif_row);
|
||||
-}
|
||||
+#define GetNextCodeLZW() do { \
|
||||
+ nextbits -= nbits; \
|
||||
+ if (nextbits < 0) { \
|
||||
+ if (dec_bitsleft >= 8 * SIZEOF_WORDTYPE) { \
|
||||
+ unsigned codetmp = (unsigned)(nextdata << (-nextbits)); \
|
||||
+ GetNextData(nextdata, bp); \
|
||||
+ bp += SIZEOF_WORDTYPE; \
|
||||
+ nextbits += 8 * SIZEOF_WORDTYPE; \
|
||||
+ dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \
|
||||
+ code = (WordType)((codetmp | (nextdata >> nextbits)) & nbitsmask); \
|
||||
+ break; \
|
||||
+ } \
|
||||
+ else {\
|
||||
+ if( dec_bitsleft < 8) { \
|
||||
+ goto no_eoi; \
|
||||
+ }\
|
||||
+ nextdata = (nextdata<<8) | *(bp)++; \
|
||||
+ nextbits += 8; \
|
||||
+ dec_bitsleft -= 8; \
|
||||
+ if( nextbits < 0 ) { \
|
||||
+ if( dec_bitsleft < 8) { \
|
||||
+ goto no_eoi; \
|
||||
+ }\
|
||||
+ nextdata = (nextdata<<8) | *(bp)++; \
|
||||
+ nextbits += 8; \
|
||||
+ dec_bitsleft -= 8; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ } \
|
||||
+ code = (WordType)((nextdata >> nextbits) & nbitsmask); \
|
||||
+} while(0)
|
||||
|
||||
static int
|
||||
LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
@@ -363,13 +392,10 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
LZWCodecState *sp = DecoderState(tif);
|
||||
char *op = (char*) op0;
|
||||
long occ = (long) occ0;
|
||||
- char *tp;
|
||||
unsigned char *bp;
|
||||
- hcode_t code;
|
||||
- int len;
|
||||
long nbits, nextbits, nbitsmask;
|
||||
- unsigned long nextdata;
|
||||
- code_t *codep, *free_entp, *maxcodep, *oldcodep;
|
||||
+ WordType nextdata;
|
||||
+ code_t *free_entp, *maxcodep, *oldcodep;
|
||||
|
||||
(void) s;
|
||||
assert(sp != NULL);
|
||||
@@ -386,7 +412,7 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
if (sp->dec_restart) {
|
||||
long residue;
|
||||
|
||||
- codep = sp->dec_codep;
|
||||
+ code_t* codep = sp->dec_codep;
|
||||
residue = codep->length - sp->dec_restart;
|
||||
if (residue > occ) {
|
||||
/*
|
||||
@@ -400,7 +426,7 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
codep = codep->next;
|
||||
} while (--residue > occ && codep);
|
||||
if (codep) {
|
||||
- tp = op + occ;
|
||||
+ uint8_t* tp = op + occ;
|
||||
do {
|
||||
*--tp = codep->value;
|
||||
codep = codep->next;
|
||||
@@ -413,7 +439,7 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
*/
|
||||
op += residue;
|
||||
occ -= residue;
|
||||
- tp = op;
|
||||
+ uint8_t* tp = op;
|
||||
do {
|
||||
int t;
|
||||
--tp;
|
||||
@@ -425,9 +451,8 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
}
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
-#ifdef LZW_CHECKEOS
|
||||
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
|
||||
-#endif
|
||||
+ uint64_t dec_bitsleft = sp->dec_bitsleft;
|
||||
nbits = sp->lzw_nbits;
|
||||
nextdata = sp->lzw_nextdata;
|
||||
nextbits = sp->lzw_nextbits;
|
||||
@@ -435,128 +460,235 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
oldcodep = sp->dec_oldcodep;
|
||||
free_entp = sp->dec_free_entp;
|
||||
maxcodep = sp->dec_maxcodep;
|
||||
+ code_t* const dec_codetab = sp->dec_codetab;
|
||||
+ code_t* codep;
|
||||
+
|
||||
+ if (occ == 0) {
|
||||
+ goto after_loop;
|
||||
+ }
|
||||
+
|
||||
+begin:
|
||||
+ {
|
||||
+ WordType code;
|
||||
+ GetNextCodeLZW();
|
||||
+ codep = dec_codetab + code;
|
||||
+ if (code >= CODE_FIRST)
|
||||
+ goto code_above_or_equal_to_258;
|
||||
+ if (code < 256)
|
||||
+ goto code_below_256;
|
||||
+ if (code == CODE_EOI)
|
||||
+ goto after_loop;
|
||||
+ goto code_clear;
|
||||
+
|
||||
+code_below_256:
|
||||
+ {
|
||||
+ if (codep > free_entp)
|
||||
+ goto error_code;
|
||||
+ free_entp->next = oldcodep;
|
||||
+ free_entp->firstchar = oldcodep->firstchar;
|
||||
+ free_entp->length = oldcodep->length+1;
|
||||
+ free_entp->value = (uint8_t)code;
|
||||
+ free_entp->repeated = (bool)(oldcodep->repeated & !(oldcodep->value - code));
|
||||
+ if (++free_entp > maxcodep) {
|
||||
+ if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */
|
||||
+ nbits = BITS_MAX;
|
||||
+ nbitsmask = MAXCODE(nbits);
|
||||
+ maxcodep = dec_codetab + nbitsmask-1;
|
||||
+ if( free_entp >= &dec_codetab[CSIZE] )
|
||||
+ {
|
||||
+ /* At that point, the next valid states are either EOI or a */
|
||||
+ /* CODE_CLEAR. If a regular code is read, at the next */
|
||||
+ /* attempt at registering a new entry, we will error out */
|
||||
+ /* due to setting free_entp before any valid code */
|
||||
+ free_entp = dec_codetab - 1;
|
||||
+ }
|
||||
+ }
|
||||
+ oldcodep = codep;
|
||||
+ *op++ = (uint8_t)code;
|
||||
+ occ--;
|
||||
+ if (occ == 0)
|
||||
+ goto after_loop;
|
||||
+ goto begin;
|
||||
+ }
|
||||
|
||||
- while (occ > 0) {
|
||||
- NextCode(tif, sp, bp, code, GetNextCode);
|
||||
- if (code == CODE_EOI)
|
||||
- break;
|
||||
- if (code == CODE_CLEAR) {
|
||||
- do {
|
||||
- free_entp = sp->dec_codetab + CODE_FIRST;
|
||||
- _TIFFmemset(free_entp, 0,
|
||||
- (CSIZE - CODE_FIRST) * sizeof (code_t));
|
||||
- nbits = BITS_MIN;
|
||||
- nbitsmask = MAXCODE(BITS_MIN);
|
||||
- maxcodep = sp->dec_codetab + nbitsmask-1;
|
||||
- NextCode(tif, sp, bp, code, GetNextCode);
|
||||
- } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
|
||||
- if (code == CODE_EOI)
|
||||
- break;
|
||||
- if (code > CODE_CLEAR) {
|
||||
- TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
|
||||
- "LZWDecode: Corrupted LZW table at scanline %"PRIu32,
|
||||
- tif->tif_row);
|
||||
- return (0);
|
||||
- }
|
||||
- *op++ = (char)code;
|
||||
- occ--;
|
||||
- oldcodep = sp->dec_codetab + code;
|
||||
- continue;
|
||||
- }
|
||||
- codep = sp->dec_codetab + code;
|
||||
-
|
||||
- /*
|
||||
- * Add the new entry to the code table.
|
||||
- */
|
||||
- if (free_entp < &sp->dec_codetab[0] ||
|
||||
- free_entp >= &sp->dec_codetab[CSIZE]) {
|
||||
- TIFFErrorExt(tif->tif_clientdata, module,
|
||||
- "Corrupted LZW table at scanline %"PRIu32,
|
||||
- tif->tif_row);
|
||||
- return (0);
|
||||
- }
|
||||
+code_above_or_equal_to_258:
|
||||
+ {
|
||||
+ /*
|
||||
+ * Add the new entry to the code table.
|
||||
+ */
|
||||
+
|
||||
+ if (codep >= free_entp)
|
||||
+ {
|
||||
+ if (codep != free_entp)
|
||||
+ goto error_code;
|
||||
+ free_entp->value = oldcodep->firstchar;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ free_entp->value = codep->firstchar;
|
||||
+ }
|
||||
+ free_entp->repeated = (bool)(oldcodep->repeated & !(oldcodep->value - free_entp->value));
|
||||
+ free_entp->next = oldcodep;
|
||||
+
|
||||
+ free_entp->firstchar = oldcodep->firstchar;
|
||||
+ free_entp->length = oldcodep->length+1;
|
||||
+ if (++free_entp > maxcodep) {
|
||||
+ if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */
|
||||
+ nbits = BITS_MAX;
|
||||
+ nbitsmask = MAXCODE(nbits);
|
||||
+ maxcodep = dec_codetab + nbitsmask-1;
|
||||
+ if (free_entp >= &dec_codetab[CSIZE])
|
||||
+ {
|
||||
+ /* At that point, the next valid states are either EOI or a */
|
||||
+ /* CODE_CLEAR. If a regular code is read, at the next */
|
||||
+ /* attempt at registering a new entry, we will error out */
|
||||
+ /* due to setting free_entp before any valid code */
|
||||
+ free_entp = dec_codetab - 1;
|
||||
+ }
|
||||
+ }
|
||||
+ oldcodep = codep;
|
||||
+
|
||||
+ /*
|
||||
+ * Code maps to a string, copy string
|
||||
+ * value to output (written in reverse).
|
||||
+ */
|
||||
+ /* tiny bit faster on x86_64 to store in unsigned short than int */
|
||||
+ unsigned short len = codep->length;
|
||||
+
|
||||
+ if (len < 3) /* equivalent to len == 2 given all other conditions */
|
||||
+ {
|
||||
+ if (occ <= 2)
|
||||
+ {
|
||||
+ if (occ == 2)
|
||||
+ {
|
||||
+ memcpy(op, &(codep->firstchar), 2);
|
||||
+ op += 2;
|
||||
+ occ -= 2;
|
||||
+ goto after_loop;
|
||||
+ }
|
||||
+ goto too_short_buffer;
|
||||
+ }
|
||||
|
||||
- free_entp->next = oldcodep;
|
||||
- if (free_entp->next < &sp->dec_codetab[0] ||
|
||||
- free_entp->next >= &sp->dec_codetab[CSIZE]) {
|
||||
- TIFFErrorExt(tif->tif_clientdata, module,
|
||||
- "Corrupted LZW table at scanline %"PRIu32,
|
||||
- tif->tif_row);
|
||||
- return (0);
|
||||
- }
|
||||
- free_entp->firstchar = free_entp->next->firstchar;
|
||||
- free_entp->length = free_entp->next->length+1;
|
||||
- free_entp->value = (codep < free_entp) ?
|
||||
- codep->firstchar : free_entp->firstchar;
|
||||
- if (++free_entp > maxcodep) {
|
||||
- if (++nbits > BITS_MAX) /* should not happen */
|
||||
- nbits = BITS_MAX;
|
||||
- nbitsmask = MAXCODE(nbits);
|
||||
- maxcodep = sp->dec_codetab + nbitsmask-1;
|
||||
- }
|
||||
- oldcodep = codep;
|
||||
- if (code >= 256) {
|
||||
- /*
|
||||
- * Code maps to a string, copy string
|
||||
- * value to output (written in reverse).
|
||||
- */
|
||||
- if(codep->length == 0) {
|
||||
- TIFFErrorExt(tif->tif_clientdata, module,
|
||||
- "Wrong length of decoded string: "
|
||||
- "data probably corrupted at scanline %"PRIu32,
|
||||
- tif->tif_row);
|
||||
- return (0);
|
||||
- }
|
||||
- if (codep->length > occ) {
|
||||
- /*
|
||||
- * String is too long for decode buffer,
|
||||
- * locate portion that will fit, copy to
|
||||
- * the decode buffer, and setup restart
|
||||
- * logic for the next decoding call.
|
||||
- */
|
||||
- sp->dec_codep = codep;
|
||||
- do {
|
||||
- codep = codep->next;
|
||||
- } while (codep && codep->length > occ);
|
||||
- if (codep) {
|
||||
- sp->dec_restart = (long)occ;
|
||||
- tp = op + occ;
|
||||
- do {
|
||||
- *--tp = codep->value;
|
||||
- codep = codep->next;
|
||||
- } while (--occ && codep);
|
||||
- if (codep)
|
||||
- codeLoop(tif, module);
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
- len = codep->length;
|
||||
- tp = op + len;
|
||||
- do {
|
||||
- int t;
|
||||
- --tp;
|
||||
- t = codep->value;
|
||||
- codep = codep->next;
|
||||
- *tp = (char)t;
|
||||
- } while (codep && tp > op);
|
||||
- if (codep) {
|
||||
- codeLoop(tif, module);
|
||||
- break;
|
||||
- }
|
||||
- assert(occ >= len);
|
||||
- op += len;
|
||||
- occ -= len;
|
||||
- } else {
|
||||
- *op++ = (char)code;
|
||||
- occ--;
|
||||
- }
|
||||
- }
|
||||
+ memcpy(op, &(codep->firstchar), 2);
|
||||
+ op += 2;
|
||||
+ occ -= 2;
|
||||
+ goto begin; /* we can save the comparison occ > 0 */
|
||||
+ }
|
||||
+
|
||||
+ if (len == 3)
|
||||
+ {
|
||||
+ if (occ <= 3)
|
||||
+ {
|
||||
+ if (occ == 3)
|
||||
+ {
|
||||
+ op[0] = codep->firstchar;
|
||||
+ op[1] = codep->next->value;
|
||||
+ op[2] = codep->value;
|
||||
+ op += 3;
|
||||
+ occ -= 3;
|
||||
+ goto after_loop;
|
||||
+ }
|
||||
+ goto too_short_buffer;
|
||||
+ }
|
||||
+ op[0] = codep->firstchar;
|
||||
+ op[1] = codep->next->value;
|
||||
+ op[2] = codep->value;
|
||||
+ op += 3;
|
||||
+ occ -= 3;
|
||||
+ goto begin; /* we can save the comparison occ > 0 */
|
||||
+ }
|
||||
+
|
||||
+ if (len > occ)
|
||||
+ {
|
||||
+ goto too_short_buffer;
|
||||
+ }
|
||||
+
|
||||
+ if (codep->repeated)
|
||||
+ {
|
||||
+ memset(op, codep->value, len);
|
||||
+ op += len;
|
||||
+ occ -= len;
|
||||
+ if (occ == 0)
|
||||
+ goto after_loop;
|
||||
+ goto begin;
|
||||
+ }
|
||||
+
|
||||
+ uint8_t* tp = op + len;
|
||||
+
|
||||
+ assert(len >= 4);
|
||||
+
|
||||
+ *--tp = codep->value;
|
||||
+ codep = codep->next;
|
||||
+ *--tp = codep->value;
|
||||
+ codep = codep->next;
|
||||
+ *--tp = codep->value;
|
||||
+ codep = codep->next;
|
||||
+ *--tp = codep->value;
|
||||
+ if (tp > op)
|
||||
+ {
|
||||
+ do {
|
||||
+ codep = codep->next;
|
||||
+ *--tp = codep->value;
|
||||
+ } while (tp > op);
|
||||
+ }
|
||||
+
|
||||
+ assert(occ >= len);
|
||||
+ op += len;
|
||||
+ occ -= len;
|
||||
+ if (occ == 0)
|
||||
+ goto after_loop;
|
||||
+ goto begin;
|
||||
+ }
|
||||
|
||||
+code_clear:
|
||||
+ {
|
||||
+ free_entp = dec_codetab + CODE_FIRST;
|
||||
+ nbits = BITS_MIN;
|
||||
+ nbitsmask = MAXCODE(BITS_MIN);
|
||||
+ maxcodep = dec_codetab + nbitsmask-1;
|
||||
+ do {
|
||||
+ GetNextCodeLZW();
|
||||
+ } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
|
||||
+ if (code == CODE_EOI)
|
||||
+ goto after_loop;
|
||||
+ if (code > CODE_EOI) {
|
||||
+ goto error_code;
|
||||
+ }
|
||||
+ *op++ = (uint8_t)code;
|
||||
+ occ--;
|
||||
+ oldcodep = dec_codetab + code;
|
||||
+ if (occ == 0)
|
||||
+ goto after_loop;
|
||||
+ goto begin;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+too_short_buffer:
|
||||
+ {
|
||||
+ /*
|
||||
+ * String is too long for decode buffer,
|
||||
+ * locate portion that will fit, copy to
|
||||
+ * the decode buffer, and setup restart
|
||||
+ * logic for the next decoding call.
|
||||
+ */
|
||||
+ sp->dec_codep = codep;
|
||||
+ do {
|
||||
+ codep = codep->next;
|
||||
+ } while (codep->length > occ);
|
||||
+
|
||||
+ sp->dec_restart = occ;
|
||||
+ uint8_t* tp = op + occ;
|
||||
+ do {
|
||||
+ *--tp = codep->value;
|
||||
+ codep = codep->next;
|
||||
+ } while (--occ);
|
||||
+ }
|
||||
+
|
||||
+after_loop:
|
||||
tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp );
|
||||
tif->tif_rawcp = (uint8_t*) bp;
|
||||
-#ifdef LZW_CHECKEOS
|
||||
sp->old_tif_rawcc = tif->tif_rawcc;
|
||||
-#endif
|
||||
+ sp->dec_bitsleft = dec_bitsleft;
|
||||
sp->lzw_nbits = (unsigned short) nbits;
|
||||
sp->lzw_nextdata = nextdata;
|
||||
sp->lzw_nextbits = nextbits;
|
||||
@@ -572,9 +704,35 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
+
|
||||
+no_eoi:
|
||||
+ TIFFErrorExt(tif->tif_clientdata, module,
|
||||
+ "LZWDecode: Strip %"PRIu32" not terminated with EOI code",
|
||||
+ tif->tif_curstrip);
|
||||
+ return 0;
|
||||
+error_code:
|
||||
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Using code not yet in table");
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
#ifdef LZW_COMPAT
|
||||
+
|
||||
+/*
|
||||
+ * This check shouldn't be necessary because each
|
||||
+ * strip is suppose to be terminated with CODE_EOI.
|
||||
+ */
|
||||
+#define NextCode(_tif, _sp, _bp, _code, _get, dec_bitsleft) { \
|
||||
+ if (dec_bitsleft < (uint64_t)nbits) { \
|
||||
+ TIFFWarningExt(_tif->tif_clientdata, module, \
|
||||
+ "LZWDecode: Strip %"PRIu32" not terminated with EOI code", \
|
||||
+ _tif->tif_curstrip); \
|
||||
+ _code = CODE_EOI; \
|
||||
+ } else { \
|
||||
+ _get(_sp,_bp,_code); \
|
||||
+ dec_bitsleft -= nbits; \
|
||||
+ } \
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Decode a "hunk of data" for old images.
|
||||
*/
|
||||
@@ -601,7 +759,8 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
unsigned char *bp;
|
||||
int code, nbits;
|
||||
int len;
|
||||
- long nextbits, nextdata, nbitsmask;
|
||||
+ long nextbits, nbitsmask;
|
||||
+ WordType nextdata;
|
||||
code_t *codep, *free_entp, *maxcodep, *oldcodep;
|
||||
|
||||
(void) s;
|
||||
@@ -653,9 +812,10 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
}
|
||||
|
||||
bp = (unsigned char *)tif->tif_rawcp;
|
||||
-#ifdef LZW_CHECKEOS
|
||||
+
|
||||
sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3);
|
||||
-#endif
|
||||
+ uint64_t dec_bitsleft = sp->dec_bitsleft;
|
||||
+
|
||||
nbits = sp->lzw_nbits;
|
||||
nextdata = sp->lzw_nextdata;
|
||||
nextbits = sp->lzw_nextbits;
|
||||
@@ -665,7 +825,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
maxcodep = sp->dec_maxcodep;
|
||||
|
||||
while (occ > 0) {
|
||||
- NextCode(tif, sp, bp, code, GetNextCodeCompat);
|
||||
+ NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft);
|
||||
if (code == CODE_EOI)
|
||||
break;
|
||||
if (code == CODE_CLEAR) {
|
||||
@@ -676,7 +836,7 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
nbits = BITS_MIN;
|
||||
nbitsmask = MAXCODE(BITS_MIN);
|
||||
maxcodep = sp->dec_codetab + nbitsmask;
|
||||
- NextCode(tif, sp, bp, code, GetNextCodeCompat);
|
||||
+ NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft);
|
||||
} while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
|
||||
if (code == CODE_EOI)
|
||||
break;
|
||||
@@ -772,9 +932,10 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
|
||||
tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp );
|
||||
tif->tif_rawcp = (uint8_t*) bp;
|
||||
-#ifdef LZW_CHECKEOS
|
||||
+
|
||||
sp->old_tif_rawcc = tif->tif_rawcc;
|
||||
-#endif
|
||||
+ sp->dec_bitsleft = dec_bitsleft;
|
||||
+
|
||||
sp->lzw_nbits = (unsigned short)nbits;
|
||||
sp->lzw_nextdata = nextdata;
|
||||
sp->lzw_nextbits = nextbits;
|
||||
@@ -893,7 +1054,7 @@ LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s)
|
||||
hcode_t ent;
|
||||
long disp;
|
||||
long incount, outcount, checkpoint;
|
||||
- unsigned long nextdata;
|
||||
+ WordType nextdata;
|
||||
long nextbits;
|
||||
int free_ent, maxcode, nbits;
|
||||
uint8_t* op;
|
||||
@@ -1057,7 +1218,7 @@ LZWPostEncode(TIFF* tif)
|
||||
register LZWCodecState *sp = EncoderState(tif);
|
||||
uint8_t* op = tif->tif_rawcp;
|
||||
long nextbits = sp->lzw_nextbits;
|
||||
- unsigned long nextdata = sp->lzw_nextdata;
|
||||
+ WordType nextdata = sp->lzw_nextdata;
|
||||
long outcount = sp->enc_outcount;
|
||||
int nbits = sp->lzw_nbits;
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
56
backport-0002-CVE-2022-1622-CVE-2022-1623.patch
Normal file
56
backport-0002-CVE-2022-1622-CVE-2022-1623.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From b4e79bfa0c7d2d08f6f1e7ec38143fc8cb11394a Mon Sep 17 00:00:00 2001
|
||||
From: Even Rouault <even.rouault@spatialys.com>
|
||||
Date: Fri, 22 Apr 2022 18:58:52 +0200
|
||||
Subject: [PATCH] tif_lzw.c: fix potential out-of-bounds error when trying to
|
||||
read in the same tile/strip after an error has occured (fixes #410)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://gitlab.com/libtiff/libtiff/-/commit/b4e79bfa0c7d2d08f6f1e7ec38143fc8cb11394a
|
||||
---
|
||||
libtiff/tif_lzw.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c
|
||||
index c28366b..1f255d9 100644
|
||||
--- a/libtiff/tif_lzw.c
|
||||
+++ b/libtiff/tif_lzw.c
|
||||
@@ -140,6 +140,7 @@ typedef struct {
|
||||
code_t* dec_free_entp; /* next free entry */
|
||||
code_t* dec_maxcodep; /* max available entry */
|
||||
code_t* dec_codetab; /* kept separate for small machines */
|
||||
+ int read_error; /* whether a read error has occured, and which should cause further reads in the same strip/tile to be aborted */
|
||||
|
||||
/* Encoding specific data */
|
||||
int enc_oldcode; /* last code encountered */
|
||||
@@ -307,6 +308,7 @@ LZWPreDecode(TIFF* tif, uint16_t s)
|
||||
*/
|
||||
sp->dec_oldcodep = &sp->dec_codetab[0];
|
||||
sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];
|
||||
+ sp->read_error = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -399,7 +401,11 @@ LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s)
|
||||
|
||||
(void) s;
|
||||
assert(sp != NULL);
|
||||
- assert(sp->dec_codetab != NULL);
|
||||
+ assert(sp->dec_codetab != NULL);
|
||||
+
|
||||
+ if (sp->read_error) {
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
/*
|
||||
Fail if value does not fit in long.
|
||||
@@ -711,6 +717,7 @@ no_eoi:
|
||||
tif->tif_curstrip);
|
||||
return 0;
|
||||
error_code:
|
||||
+ sp->read_error = 1;
|
||||
TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Using code not yet in table");
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: libtiff
|
||||
Version: 4.3.0
|
||||
Release: 14
|
||||
Release: 15
|
||||
Summary: TIFF Library and Utilities
|
||||
License: libtiff
|
||||
URL: https://www.simplesystems.org/libtiff/
|
||||
@ -18,6 +18,9 @@ Patch6008: backport-CVE-2022-0865.patch
|
||||
Patch6009: backport-CVE-2022-0909.patch
|
||||
Patch6010: backport-CVE-2022-0924.patch
|
||||
Patch6011: backport-CVE-2022-1355.patch
|
||||
Patch6012: backport-0001-CVE-2022-1622-CVE-2022-1623.patch
|
||||
Patch6013: backport-0002-CVE-2022-1622-CVE-2022-1623.patch
|
||||
|
||||
|
||||
Patch9000: fix-raw2tiff-floating-point-exception.patch
|
||||
|
||||
@ -140,6 +143,9 @@ find html -name 'Makefile*' | xargs rm
|
||||
%exclude %{_datadir}/html/man/tiffgt.1.html
|
||||
|
||||
%changelog
|
||||
* Tue Jun 14 2022 wuchaochao <cyanrose@yeah.net> - 4.3.0-15
|
||||
- fix CVE-2022-1622 and CVE-2022-1623
|
||||
|
||||
* Sat Jun 11 2022 wangkerong <wangkerong@h-partners.com> - 4.3.0-14
|
||||
- delete macro in changelog
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user