]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
[linux] Port libzstd UBSAN fix
authorNick Terrell <terrelln@fb.com>
Mon, 19 Jun 2017 22:48:30 +0000 (15:48 -0700)
committerNick Terrell <terrelln@fb.com>
Mon, 19 Jun 2017 22:48:30 +0000 (15:48 -0700)
contrib/linux-kernel/lib/zstd/compress.c
contrib/linux-kernel/zstd.diff

index 42236a3e1e1a19ba24484eea65d2571767f44b7c..1aff542b0df1dc2410c2c7f004de5031fcc870b2 100644 (file)
@@ -1978,10 +1978,15 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx *ctx, const void *src, size_t src
                                break; /* nothing found : store previous solution */
                        }
 
+               /* NOTE:
+                * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
+                * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
+                * overflows the pointer, which is undefined behavior.
+                */
                /* catch up */
                if (offset) {
                        while ((start > anchor) && (start > base + offset - ZSTD_REP_MOVE) &&
-                              (start[-1] == start[-1 - offset + ZSTD_REP_MOVE])) /* only search for offset within prefix */
+                              (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1])) /* only search for offset within prefix */
                        {
                                start--;
                                matchLength++;
index 1fa64ff868c8d7a0e636d1e98e064687671eb8b5..e83b56ed2acadd0273573e0a683d73612887b0df 100644 (file)
@@ -1599,10 +1599,10 @@ index 0000000..a826b99
 +#endif /* BITSTREAM_H_MODULE */
 diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c
 new file mode 100644
-index 0000000..42236a3
+index 0000000..1aff542
 --- /dev/null
 +++ b/lib/zstd/compress.c
-@@ -0,0 +1,3463 @@
+@@ -0,0 +1,3468 @@
 +/**
 + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
 + * All rights reserved.
@@ -3583,10 +3583,15 @@ index 0000000..42236a3
 +                              break; /* nothing found : store previous solution */
 +                      }
 +
++              /* NOTE:
++               * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
++               * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
++               * overflows the pointer, which is undefined behavior.
++               */
 +              /* catch up */
 +              if (offset) {
 +                      while ((start > anchor) && (start > base + offset - ZSTD_REP_MOVE) &&
-+                             (start[-1] == start[-1 - offset + ZSTD_REP_MOVE])) /* only search for offset within prefix */
++                             (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1])) /* only search for offset within prefix */
 +                      {
 +                              start--;
 +                              matchLength++;