mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
94 lines
1.8 KiB
C++
94 lines
1.8 KiB
C++
#if ! defined(_GNU_SOURCE)
|
|
#define _GNU_SOURCE
|
|
#endif
|
|
|
|
#ifdef _MSC_VER
|
|
#include <mem.h>
|
|
#endif
|
|
|
|
#include "zeek/fuzzers/FuzzBuffer.h"
|
|
|
|
#include <cstring>
|
|
|
|
namespace zeek::detail
|
|
{
|
|
|
|
bool 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 ( ExceedsChunkLimit(chunk_count_limit) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
int FuzzBuffer::ChunkCount(int chunk_count_limit) const
|
|
{
|
|
auto pos = begin;
|
|
int chunks = 0;
|
|
|
|
while ( pos < end && (chunks < chunk_count_limit || chunk_count_limit == 0) )
|
|
{
|
|
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<FuzzBuffer::Chunk> 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<unsigned char[]>(rval.size);
|
|
memcpy(rval.data.get(), chunk_begin, rval.size);
|
|
return {std::move(rval)};
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
} // namespace zeek::detail
|