Skip to content

When decompressing truncated input, calling ZSTD_decompressStream() with input = {NULL, 0, 0} computes NULL + 0, which is UB #3351

@QrczakMK

Description

@QrczakMK

Describe the bug
At least in certain circumstances, when decompressing truncated compressed input, calling ZSTD_decompressStream() with input = {NULL, 0, 0} computes NULL + 0 here:

ip += loadedSize;

which is UB in C, detected by ubsan (nullptr-with-offset), even though it is benign in practice.

To Reproduce
I could try extracting a test case, but I would prefer to avoid unnecessary work. The fix should be uncontroversial.

Expected behavior
Decompression successfully stops wanting more input, even under ubsan.

Possible fix:

--- a/google3/third_party/zstdlib/decompress/zstd_decompress.c
+++ b/google3/third_party/zstdlib/decompress/zstd_decompress.c
@@ -2166,8 +2166,10 @@ size_t ZSTD_decompressStream(ZSTD_DStrea
                                     "should never happen");
                     loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
                 }
-                ip += loadedSize;
-                zds->inPos += loadedSize;
+                if (loadedSize != 0) {
+                    ip += loadedSize;
+                    zds->inPos += loadedSize;
+                }
                 if (loadedSize < toLoad) { someMoreWork = 0; break; }   /* not enough input, wait for more */
 
                 /* decode loaded input */

Our randomized tests succeed with this fix many times, which suggests that this is the only place to fix for this issue.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions