#if !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif #include #include "FuzzBuffer.h" bool zeek::detail::FuzzBuffer::Valid(int chunk_count_limit) const { if ( end - begin < PKT_MAGIC_LEN + 2 ) return false; if ( memcmp(begin, PKT_MAGIC, PKT_MAGIC_LEN) != 0) return false; if ( ChunkCount(chunk_count_limit + 1) > chunk_count_limit ) return false; return true; } int zeek::detail::FuzzBuffer::ChunkCount(int chunk_count_limit) const { auto pos = begin; int chunks = 0; while ( pos < end && (chunk_count_limit == 0 || chunks < chunk_count_limit) ) { pos = (const unsigned char*)memmem(pos, end - pos, PKT_MAGIC, PKT_MAGIC_LEN); if ( ! pos ) break; pos += PKT_MAGIC_LEN + 1; chunks++; } return chunks; } std::optional zeek::detail::FuzzBuffer::Next() { if ( begin == end ) return {}; auto pos = (const unsigned char*)memmem(begin, end - begin, PKT_MAGIC, PKT_MAGIC_LEN); if ( ! pos ) return {}; begin += PKT_MAGIC_LEN; auto remaining = end - begin; if ( remaining < 2 ) return {}; Chunk rval; rval.is_orig = begin[0] & 0x01; begin += 1; auto chunk_begin = begin; auto next = (const unsigned char*)memmem(begin, end - begin, PKT_MAGIC, PKT_MAGIC_LEN); if ( next ) begin = next; else begin = end; rval.size = begin - chunk_begin; if ( rval.size ) { // The point of allocating a new buffer here is to better detect // analyzers that may over-read within a chunk -- ASan wouldn't // complain if that happens to land within the full input buffer // provided by the fuzzing engine, but will if we allocate a new buffer // for each chunk. rval.data = std::make_unique(rval.size); memcpy(rval.data.get(), chunk_begin, rval.size); return {std::move(rval)}; } return {}; }