Skip to content

Commit bda947e

Browse files
committed
[huf] Fix bug in fast C decoders
The input bounds checks were buggy because they were only breaking from the inner loop, not the outer loop. The fuzzers found this immediately. The fix is to use `goto _out` instead of `break`. This condition can happen on corrupted inputs. I've benchmarked before and after on x86-64 and there were small changes in performance, some positive, and some negative, and they end up about balacing out. Credit to OSS-Fuzz
1 parent 7b3f03b commit bda947e

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

lib/decompress/huf_decompress.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
742742
*/
743743
for (stream = 1; stream < 4; ++stream) {
744744
if (ip[stream] < ip[stream - 1])
745-
break;
745+
goto _out;
746746
}
747747
}
748748

@@ -775,6 +775,8 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
775775
} while (op[3] < olimit);
776776
}
777777

778+
_out:
779+
778780
/* Save the final values of each of the state variables back to args. */
779781
ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
780782
ZSTD_memcpy(&args->ip, &ip, sizeof(ip));
@@ -1535,7 +1537,7 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
15351537
*/
15361538
for (stream = 1; stream < 4; ++stream) {
15371539
if (ip[stream] < ip[stream - 1])
1538-
break;
1540+
goto _out;
15391541
}
15401542
}
15411543

@@ -1593,6 +1595,8 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
15931595
} while (op[3] < olimit);
15941596
}
15951597

1598+
_out:
1599+
15961600
/* Save the final values of each of the state variables back to args. */
15971601
ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
15981602
ZSTD_memcpy(&args->ip, &ip, sizeof(ip));

0 commit comments

Comments
 (0)