1
0
mirror of https://git.tukaani.org/xz.git synced 2025-04-15 04:00:50 +00:00

Tests: Call lzma_code() in smaller chunks in fuzz_common.h

This makes it easy to crash fuzz_decode_stream_mt when tested
against the code from 5.8.0.

Obviously this might make it harder to reach some other code path now.
The previous code has been in use since 2018 when fuzzing was added
in 106d1a663d4b ("Tests: Add a fuzz test program and a config file
for OSS-Fuzz.").
This commit is contained in:
Lasse Collin 2025-04-03 14:34:43 +03:00
parent 48440e24a2
commit 513cabcf7f
No known key found for this signature in database
GPG Key ID: 38EE757D69184620

View File

@ -20,6 +20,9 @@
// prevent extreme allocations when fuzzing.
#define MEM_LIMIT (300 << 20) // 300 MiB
// Amount of input to pass to lzma_code() per call at most.
#define IN_CHUNK_SIZE 2047
static void
fuzz_code(lzma_stream *stream, const uint8_t *inbuf, size_t inbuf_size) {
@ -27,15 +30,29 @@ fuzz_code(lzma_stream *stream, const uint8_t *inbuf, size_t inbuf_size) {
// cares about the actual data written here.
uint8_t outbuf[4096];
// Give the whole input buffer at once to liblzma.
// Output buffer isn't initialized as liblzma only writes to it.
// Pass half of the input on the first call and then proceed in
// chunks. It's fine that this rounds to 0 when inbuf_size is 1.
stream->next_in = inbuf;
stream->avail_in = inbuf_size;
stream->next_out = outbuf;
stream->avail_out = sizeof(outbuf);
stream->avail_in = inbuf_size / 2;
lzma_action action = LZMA_RUN;
lzma_ret ret;
while ((ret = lzma_code(stream, LZMA_FINISH)) == LZMA_OK) {
do {
if (stream->avail_in == 0 && inbuf_size > 0) {
const size_t chunk_size = inbuf_size < IN_CHUNK_SIZE
? inbuf_size : IN_CHUNK_SIZE;
stream->next_in = inbuf;
stream->avail_in = chunk_size;
inbuf += chunk_size;
inbuf_size -= chunk_size;
if (inbuf_size == 0)
action = LZMA_FINISH;
}
if (stream->avail_out == 0) {
// outbuf became full. We don't care about the
// uncompressed data there, so we simply reuse
@ -43,7 +60,7 @@ fuzz_code(lzma_stream *stream, const uint8_t *inbuf, size_t inbuf_size) {
stream->next_out = outbuf;
stream->avail_out = sizeof(outbuf);
}
}
} while ((ret = lzma_code(stream, action)) == LZMA_OK);
// LZMA_PROG_ERROR should never happen as long as the code calling
// the liblzma functions is correct. Thus LZMA_PROG_ERROR is a sign