]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Fixed memory initialization issue, reported by Maciej Adamczyk
authorYann Collet <yann.collet.73@gmail.com>
Thu, 7 Apr 2016 17:35:23 +0000 (19:35 +0200)
committerYann Collet <yann.collet.73@gmail.com>
Thu, 7 Apr 2016 17:35:23 +0000 (19:35 +0200)
lib/zbuff.c
lib/zstd_decompress.c
programs/fileio.c

index b0225e8574fc142546add18bb2feef8196542ece..eab0c482bb5f9e4425a7c03db26cbc278658fbd7 100644 (file)
@@ -319,7 +319,7 @@ typedef enum { ZBUFFds_init, ZBUFFds_readHeader,
 
 /* *** Resource management *** */
 struct ZBUFF_DCtx_s {
-    ZSTD_DCtx* zc;
+    ZSTD_DCtx* zd;
     ZSTD_frameParams fParams;
     size_t blockSize;
     char*  inBuff;
@@ -335,63 +335,63 @@ struct ZBUFF_DCtx_s {
 
 ZBUFF_DCtx* ZBUFF_createDCtx(void)
 {
-    ZBUFF_DCtx* zbc = (ZBUFF_DCtx*)malloc(sizeof(ZBUFF_DCtx));
-    if (zbc==NULL) return NULL;
-    memset(zbc, 0, sizeof(*zbc));
-    zbc->zc = ZSTD_createDCtx();
-    zbc->stage = ZBUFFds_init;
-    return zbc;
+    ZBUFF_DCtx* zbd = (ZBUFF_DCtx*)malloc(sizeof(ZBUFF_DCtx));
+    if (zbd==NULL) return NULL;
+    memset(zbd, 0, sizeof(*zbd));
+    zbd->zd = ZSTD_createDCtx();
+    zbd->stage = ZBUFFds_init;
+    return zbd;
 }
 
-size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbc)
+size_t ZBUFF_freeDCtx(ZBUFF_DCtx* zbd)
 {
-    if (zbc==NULL) return 0;   /* support free on null */
-    ZSTD_freeDCtx(zbc->zc);
-    free(zbc->inBuff);
-    free(zbc->outBuff);
-    free(zbc);
+    if (zbd==NULL) return 0;   /* support free on null */
+    ZSTD_freeDCtx(zbd->zd);
+    free(zbd->inBuff);
+    free(zbd->outBuff);
+    free(zbd);
     return 0;
 }
 
 
 /* *** Initialization *** */
 
-size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* zbc, const void* dict, size_t dictSize)
+size_t ZBUFF_decompressInitDictionary(ZBUFF_DCtx* zbd, const void* dict, size_t dictSize)
 {
-    zbc->stage = ZBUFFds_readHeader;
-    zbc->inPos = zbc->outStart = zbc->outEnd = 0;
-    return ZSTD_decompressBegin_usingDict(zbc->zc, dict, dictSize);
+    zbd->stage = ZBUFFds_readHeader;
+    zbd->inPos = zbd->outStart = zbd->outEnd = 0;
+    return ZSTD_decompressBegin_usingDict(zbd->zd, dict, dictSize);
 }
 
-size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbc)
+size_t ZBUFF_decompressInit(ZBUFF_DCtx* zbd)
 {
-    return ZBUFF_decompressInitDictionary(zbc, NULL, 0);
+    return ZBUFF_decompressInitDictionary(zbd, NULL, 0);
 }
 
 
 /* *** Decompression *** */
 
-size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc,
+size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbd,
                                 void* dst, size_t* dstCapacityPtr,
                           const void* src, size_t* srcSizePtr)
 {
     const char* const istart = (const char*)src;
-    const char* ip = istart;
     const char* const iend = istart + *srcSizePtr;
+    const char* ip = istart;
     char* const ostart = (char*)dst;
-    char* op = ostart;
     char* const oend = ostart + *dstCapacityPtr;
+    char* op = ostart;
     U32 notDone = 1;
 
     while (notDone) {
-        switch(zbc->stage)
+        switch(zbd->stage)
         {
         case ZBUFFds_init :
             return ERROR(init_missing);
 
         case ZBUFFds_readHeader :
             /* read header from src */
-            {   size_t const headerSize = ZSTD_getFrameParams(&(zbc->fParams), src, *srcSizePtr);
+            {   size_t const headerSize = ZSTD_getFrameParams(&(zbd->fParams), src, *srcSizePtr);
                 if (ZSTD_isError(headerSize)) return headerSize;
                 if (headerSize) {
                     /* not enough input to decode header : needs headerSize > *srcSizePtr */
@@ -401,76 +401,76 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc,
             }   }
 
             /* Frame header instruct buffer sizes */
-            {   size_t const blockSize = MIN(1 << zbc->fParams.windowLog, ZSTD_BLOCKSIZE_MAX);
-                zbc->blockSize = blockSize;
-                if (zbc->inBuffSize < blockSize) {
-                    free(zbc->inBuff);
-                    zbc->inBuffSize = blockSize;
-                    zbc->inBuff = (char*)malloc(blockSize);
-                    if (zbc->inBuff == NULL) return ERROR(memory_allocation);
+            {   size_t const blockSize = MIN(1 << zbd->fParams.windowLog, ZSTD_BLOCKSIZE_MAX);
+                zbd->blockSize = blockSize;
+                if (zbd->inBuffSize < blockSize) {
+                    free(zbd->inBuff);
+                    zbd->inBuffSize = blockSize;
+                    zbd->inBuff = (char*)malloc(blockSize);
+                    if (zbd->inBuff == NULL) return ERROR(memory_allocation);
                 }
-                {   size_t const neededOutSize = ((size_t)1 << zbc->fParams.windowLog) + blockSize;
-                    if (zbc->outBuffSize < neededOutSize) {
-                        free(zbc->outBuff);
-                        zbc->outBuffSize = neededOutSize;
-                        zbc->outBuff = (char*)malloc(neededOutSize);
-                        if (zbc->outBuff == NULL) return ERROR(memory_allocation);
+                {   size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize;
+                    if (zbd->outBuffSize < neededOutSize) {
+                        free(zbd->outBuff);
+                        zbd->outBuffSize = neededOutSize;
+                        zbd->outBuff = (char*)malloc(neededOutSize);
+                        if (zbd->outBuff == NULL) return ERROR(memory_allocation);
             }   }   }
-            zbc->stage = ZBUFFds_read;
+            zbd->stage = ZBUFFds_read;
 
         case ZBUFFds_read:
-            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);
+            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd);
                 if (neededInSize==0) {  /* end of frame */
-                    zbc->stage = ZBUFFds_init;
+                    zbd->stage = ZBUFFds_init;
                     notDone = 0;
                     break;
                 }
                 if ((size_t)(iend-ip) >= neededInSize) {
                     /* directly decode from src */
-                    size_t const decodedSize = ZSTD_decompressContinue(zbc->zc,
-                        zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart,
+                    size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
+                        zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
                         ip, neededInSize);
                     if (ZSTD_isError(decodedSize)) return decodedSize;
                     ip += neededInSize;
                     if (!decodedSize) break;   /* this was just a header */
-                    zbc->outEnd = zbc->outStart +  decodedSize;
-                    zbc->stage = ZBUFFds_flush;
+                    zbd->outEnd = zbd->outStart +  decodedSize;
+                    zbd->stage = ZBUFFds_flush;
                     break;
                 }
                 if (ip==iend) { notDone = 0; break; }   /* no more input */
-                zbc->stage = ZBUFFds_load;
+                zbd->stage = ZBUFFds_load;
             }
 
         case ZBUFFds_load:
-            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);
-                size_t const toLoad = neededInSize - zbc->inPos;   /* should always be <= remaining space within inBuff */
+            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zbd->zd);
+                size_t const toLoad = neededInSize - zbd->inPos;   /* should always be <= remaining space within inBuff */
                 size_t loadedSize;
-                if (toLoad > zbc->inBuffSize - zbc->inPos) return ERROR(corruption_detected);   /* should never happen */
-                loadedSize = ZBUFF_limitCopy(zbc->inBuff + zbc->inPos, toLoad, ip, iend-ip);
+                if (toLoad > zbd->inBuffSize - zbd->inPos) return ERROR(corruption_detected);   /* should never happen */
+                loadedSize = ZBUFF_limitCopy(zbd->inBuff + zbd->inPos, toLoad, ip, iend-ip);
                 ip += loadedSize;
-                zbc->inPos += loadedSize;
+                zbd->inPos += loadedSize;
                 if (loadedSize < toLoad) { notDone = 0; break; }   /* not enough input, wait for more */
                 /* decode loaded input */
-                {   size_t const decodedSize = ZSTD_decompressContinue(zbc->zc,
-                        zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart,
-                        zbc->inBuff, neededInSize);
+                {   size_t const decodedSize = ZSTD_decompressContinue(zbd->zd,
+                        zbd->outBuff + zbd->outStart, zbd->outBuffSize - zbd->outStart,
+                        zbd->inBuff, neededInSize);
                     if (ZSTD_isError(decodedSize)) return decodedSize;
-                    zbc->inPos = 0;   /* input is consumed */
-                    if (!decodedSize) { zbc->stage = ZBUFFds_read; break; }   /* this was just a header */
-                    zbc->outEnd = zbc->outStart +  decodedSize;
-                    zbc->stage = ZBUFFds_flush;
+                    zbd->inPos = 0;   /* input is consumed */
+                    if (!decodedSize) { zbd->stage = ZBUFFds_read; break; }   /* this was just a header */
+                    zbd->outEnd = zbd->outStart +  decodedSize;
+                    zbd->stage = ZBUFFds_flush;
                     // break; /* ZBUFFds_flush follows */
             }   }
 
         case ZBUFFds_flush:
-            {   size_t const toFlushSize = zbc->outEnd - zbc->outStart;
-                size_t const flushedSize = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outStart, toFlushSize);
+            {   size_t const toFlushSize = zbd->outEnd - zbd->outStart;
+                size_t const flushedSize = ZBUFF_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
                 op += flushedSize;
-                zbc->outStart += flushedSize;
+                zbd->outStart += flushedSize;
                 if (flushedSize == toFlushSize) {
-                    zbc->stage = ZBUFFds_read;
-                    if (zbc->outStart + zbc->blockSize > zbc->outBuffSize)
-                        zbc->outStart = zbc->outEnd = 0;
+                    zbd->stage = ZBUFFds_read;
+                    if (zbd->outStart + zbd->blockSize > zbd->outBuffSize)
+                        zbd->outStart = zbd->outEnd = 0;
                     break;
                 }
                 /* cannot flush everything */
@@ -483,9 +483,9 @@ size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc,
     /* result */
     *srcSizePtr = ip-istart;
     *dstCapacityPtr = op-ostart;
-    {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbc->zc);
+    {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zbd->zd);
         if (nextSrcSizeHint > ZSTD_blockHeaderSize) nextSrcSizeHint+= ZSTD_blockHeaderSize;   /* get following block header too */
-        nextSrcSizeHint -= zbc->inPos;   /* already loaded*/
+        nextSrcSizeHint -= zbd->inPos;   /* already loaded*/
         return nextSrcSizeHint;
     }
 }
index 60595b45c88024693bf73ed27e1ae74434f45992..a85ee2b5c34f04fdcce33ddf072b177a91db54f9 100644 (file)
@@ -400,6 +400,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
                 break;
             }
             if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
+            if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
 
             if (HUF_isError(singleStream ?
                             HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
index d5893f1a657c089b3702b980cf9f0e6350b52022..ec0d19f218a84a635b71d60e19f426fd7b79cdf9 100644 (file)
@@ -567,7 +567,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress,
     /* Complete Header loading */
     {   size_t const toLoad = ZSTD_frameHeaderSize_max - alreadyLoaded;   /* assumption : alreadyLoaded <= ZSTD_frameHeaderSize_max */
         size_t const checkSize = fread(((char*)ress.srcBuffer) + alreadyLoaded, 1, toLoad, finput);
-        if (checkSize != toLoad) EXM_THROW(32, "Read error");
+        if (checkSize != toLoad) EXM_THROW(32, "Read error");   /* assumption : srcSize >= ZSTD_frameHeaderSize_max */
     }
     readSize = ZSTD_frameHeaderSize_max;
 
@@ -581,7 +581,7 @@ unsigned long long FIO_decompressFrame(dRess_t ress,
 
         /* Write block */
         { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput);
-        if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block into destination"); }
+          if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block into destination"); }
         frameSize += decodedSize;
         DISPLAYUPDATE(2, "\rDecoded : %u MB...     ", (U32)(frameSize>>20) );
 
@@ -613,10 +613,9 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* srcFileName)
 
     /* for each frame */
     for ( ; ; ) {
-        size_t sizeCheck;
         /* check magic number -> version */
-        size_t toRead = 4;
-        sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile);
+        size_t const toRead = 4;
+        size_t const sizeCheck = fread(ress.srcBuffer, (size_t)1, toRead, srcFile);
         if (sizeCheck==0) break;   /* no more input */
         if (sizeCheck != toRead) EXM_THROW(31, "zstd: %s read error : cannot read header", srcFileName);
 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)