1
0
Fork 0
virtualbox/include/iprt/fuzz.h
Daniel Baumann df1bda4fe9
Adding upstream version 7.0.20-dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 09:56:04 +02:00

971 lines
36 KiB
C

/** @file
* IPRT - Fuzzing framework
*/
/*
* Copyright (C) 2018-2023 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, in version 3 of the
* License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses>.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
* in the VirtualBox distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
*/
#ifndef IPRT_INCLUDED_fuzz_h
#define IPRT_INCLUDED_fuzz_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <iprt/cdefs.h>
#include <iprt/process.h>
#include <iprt/types.h>
RT_C_DECLS_BEGIN
/** @defgroup grp_rt_fuzz RTFuzz - Data fuzzing framework
* @ingroup grp_rt
* @sa grp_rt_test
* @{
*/
/** A fuzzer context handle. */
typedef struct RTFUZZCTXINT *RTFUZZCTX;
/** Pointer to a fuzzer context handle. */
typedef RTFUZZCTX *PRTFUZZCTX;
/** NIL fuzzer context handle. */
#define NIL_RTFUZZCTX ((RTFUZZCTX)~(uintptr_t)0)
/** A fuzzer input handle. */
typedef struct RTFUZZINPUTINT *RTFUZZINPUT;
/** Pointer to a fuzzer input handle. */
typedef RTFUZZINPUT *PRTFUZZINPUT;
/** NIL fuzzer input handle. */
#define NIL_RTFUZZINPUT ((RTFUZZINPUT)~(uintptr_t)0)
/** A fuzzer config handle. */
typedef struct RTFUZZCFGINT *RTFUZZCFG;
/** Pointer to a fuzzer config handle. */
typedef RTFUZZCFG *PRTFUZZCFG;
/** NIL fuzzer config handle. */
#define NIL_RTFUZZCFG ((RTFUZZCFG)~(uintptr_t)0)
/** A fuzzer target recorder handler. */
typedef struct RTFUZZTGTRECINT *RTFUZZTGTREC;
/** Pointer to a fuzzer target recorder handle. */
typedef RTFUZZTGTREC *PRTFUZZTGTREC;
/** NIL fuzzer target recorder handle. */
#define NIL_RTFUZZTGTREC ((RTFUZZTGTREC)~(uintptr_t)0)
/** A fuzzed target state handle. */
typedef struct RTFUZZTGTSTATEINT *RTFUZZTGTSTATE;
/** Pointer to a fuzzed target state handle. */
typedef RTFUZZTGTSTATE *PRTFUZZTGTSTATE;
/** NIL fuzzed target state handle. */
#define NIL_RTFUZZTGTSTATE ((RTFUZZTGTSTATE)~(uintptr_t)0)
/** Fuzzing observer handle. */
typedef struct RTFUZZOBSINT *RTFUZZOBS;
/** Pointer to a fuzzing observer handle. */
typedef RTFUZZOBS *PRTFUZZOBS;
/** NIL fuzzing observer handle. */
#define NIL_RTFUZZOBS ((RTFUZZOBS)~(uintptr_t)0)
/**
* Fuzzing context type.
*/
typedef enum RTFUZZCTXTYPE
{
/** Invalid type. */
RTFUZZCTXTYPE_INVALID = 0,
/** Original input data is a single binary large object (BLOB), from a file or similar. */
RTFUZZCTXTYPE_BLOB,
/** Original input data is from a data stream like a network connection. */
RTFUZZCTXTYPE_STREAM,
/** 32bit hack. */
RTFUZZCTXTYPE_32BIT_HACK = 0x7fffffff
} RTFUZZCTXTYPE;
/**
* Fuzzing context statistics.
*/
typedef struct RTFUZZCTXSTATS
{
/** Amount of memory currently allocated. */
size_t cbMemory;
/** Number of mutations accumulated in the corpus. */
uint64_t cMutations;
} RTFUZZCTXSTATS;
/** Pointer to fuzzing context statistics. */
typedef RTFUZZCTXSTATS *PRTFUZZCTXSTATS;
/** @name RTFUZZCTX_F_XXX - Flags for RTFuzzCtxCfgSetBehavioralFlags
* @{ */
/** Adds all generated inputs automatically to the input corpus for the owning context. */
#define RTFUZZCTX_F_BEHAVIORAL_ADD_INPUT_AUTOMATICALLY_TO_CORPUS RT_BIT_32(0)
/** All valid behavioral modification flags. */
#define RTFUZZCTX_F_BEHAVIORAL_VALID (RTFUZZCTX_F_BEHAVIORAL_ADD_INPUT_AUTOMATICALLY_TO_CORPUS)
/** @} */
/** @name RTFUZZOBS_SANITIZER_F_XXX - Flags for RTFuzzObsSetTestBinarySanitizers().
* @{ */
/** ASAN is compiled and enabled (observer needs to configure to abort on error to catch memory errors). */
#define RTFUZZOBS_SANITIZER_F_ASAN UINT32_C(0x00000001)
/** A converage sanitizer is compiled in which can be used to produce coverage reports aiding in the
* fuzzing process. */
#define RTFUZZOBS_SANITIZER_F_SANCOV UINT32_C(0x00000002)
/** @} */
/** @name RTFUZZTGT_REC_STATE_F_XXX - Flags for RTFuzzTgtRecorderCreate().
* @{ */
/** The output from stdout is used to compare states. */
#define RTFUZZTGT_REC_STATE_F_STDOUT RT_BIT_32(0)
/** The output from stderr is used to compare states. */
#define RTFUZZTGT_REC_STATE_F_STDERR RT_BIT_32(1)
/** The process status is used to compare states. */
#define RTFUZZTGT_REC_STATE_F_PROCSTATUS RT_BIT_32(2)
/** The coverage report is used to compare states. */
#define RTFUZZTGT_REC_STATE_F_SANCOV RT_BIT_32(3)
/** Mask of all valid flags. */
#define RTFUZZTGT_REC_STATE_F_VALID UINT32_C(0x0000000f)
/** @} */
/** @name RTFUZZCFG_IMPORT_F_XXX - Flags for RTFuzzCfgImport().
* @{ */
/** Default flags. */
#define RTFUZZCFG_IMPORT_F_DEFAULT 0
/** Adds only the inputs and doesn't set any glboal configuration flags of the fuzzing context. */
#define RTFUZZCFG_IMPORT_F_ONLY_INPUT RT_BIT_32(0)
/** Mask of all valid flags. */
#define RTFUZZCFG_IMPORT_F_VALID UINT32_C(0x00000001)
/** @} */
/**
* Fuzzing context state export callback.
*
* @returns IPRT status code.
* @param hFuzzCtx Handle of the fuzzing context.
* @param pvBuf The data to write.
* @param cbWrite Number of bytes to write.
* @param pvUser Opaque user data passed in RTFuzzCtxStateExport().
*/
typedef DECLCALLBACKTYPE(int, FNRTFUZZCTXEXPORT,(RTFUZZCTX hFuzzCtx, const void *pvBuf, size_t cbWrite, void *pvUser));
/** Pointer to a fuzzing context state export callback. */
typedef FNRTFUZZCTXEXPORT *PFNRTFUZZCTXEXPORT;
/**
* Fuzzing context state import callback.
*
* @returns IPRT status code.
* @param hFuzzCtx Handle of the fuzzing context.
* @param pvBuf Where to store the read data.
* @param cbRead Number of bytes to read.
* @param pcbRead Where to store the amount of data written, optional.
* @param pvUser Opaque user data passed in RTFuzzCtxCreateFromState().
*/
typedef DECLCALLBACKTYPE(int, FNRTFUZZCTXIMPORT,(RTFUZZCTX hFuzzCtx, void *pvBuf, size_t cbRead, size_t *pcbRead, void *pvUser));
/** Pointer to a fuzzing context state export callback. */
typedef FNRTFUZZCTXIMPORT *PFNRTFUZZCTXIMPORT;
/**
* Creates a new fuzzing context.
*
* @returns IPRT status code.
* @param phFuzzCtx Where to store the handle to the fuzzing context on success.
* @param enmType Fuzzing context data type.
*/
RTDECL(int) RTFuzzCtxCreate(PRTFUZZCTX phFuzzCtx, RTFUZZCTXTYPE enmType);
/**
* Creates a new fuzzing context from the given state.
*
* @returns IPRT status code.
* @param phFuzzCtx Where to store the handle to the fuzzing context on success.
* @param pfnImport State import callback.
* @param pvUser Opaque user data to pass to the callback.
*/
RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, PFNRTFUZZCTXIMPORT pfnImport, void *pvUser);
/**
* Creates a new fuzzing context loading the state from the given memory buffer.
*
* @returns IPRT status code.
* @param phFuzzCtx Where to store the handle to the fuzzing context on success.
* @param pvState Pointer to the memory containing the state.
* @param cbState Size of the state buffer.
*/
RTDECL(int) RTFuzzCtxCreateFromStateMem(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState);
/**
* Creates a new fuzzing context loading the state from the given file.
*
* @returns IPRT status code.
* @param phFuzzCtx Where to store the handle to the fuzzing context on success.
* @param pszFilename File to load the fuzzing context from.
*/
RTDECL(int) RTFuzzCtxCreateFromStateFile(PRTFUZZCTX phFuzzCtx, const char *pszFilename);
/**
* Retains a reference to the given fuzzing context.
*
* @returns New reference count on success.
* @param hFuzzCtx Handle of the fuzzing context.
*/
RTDECL(uint32_t) RTFuzzCtxRetain(RTFUZZCTX hFuzzCtx);
/**
* Releases a reference from the given fuzzing context, destroying it when reaching 0.
*
* @returns New reference count on success, 0 if the fuzzing context got destroyed.
* @param hFuzzCtx Handle of the fuzzing context.
*/
RTDECL(uint32_t) RTFuzzCtxRelease(RTFUZZCTX hFuzzCtx);
/**
* Queries statistics about the given fuzzing context.
*
* @returns IPRT status code.
* @param hFuzzCtx Handle of the fuzzing context.
* @param pStats Where to store the stats on success.
*/
RTDECL(int) RTFuzzCtxQueryStats(RTFUZZCTX hFuzzCtx, PRTFUZZCTXSTATS pStats);
/**
* Exports the given fuzzing context state.
*
* @returns IPRT statuse code
* @param hFuzzCtx The fuzzing context to export.
* @param pfnExport Export callback.
* @param pvUser Opaque user data to pass to the callback.
*/
RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, PFNRTFUZZCTXEXPORT pfnExport, void *pvUser);
/**
* Exports the given fuzzing context state to memory allocating the buffer.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context to export.
* @param ppvState Where to store the pointer to the memory containing state on success.
* Free with RTMemFree().
* @param pcbState Where to store the size of the state in bytes.
*/
RTDECL(int) RTFuzzCtxStateExportToMem(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState);
/**
* Exports the given fuzzing context state to the given file.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context to export.
* @param pszFilename The file to save the state to.
*/
RTDECL(int) RTFuzzCtxStateExportToFile(RTFUZZCTX hFuzzCtx, const char *pszFilename);
/**
* Adds a new seed to the input corpus of the given fuzzing context.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param pvInput The pointer to the input buffer.
* @param cbInput Size of the input buffer.
*/
RTDECL(int) RTFuzzCtxCorpusInputAdd(RTFUZZCTX hFuzzCtx, const void *pvInput, size_t cbInput);
/**
* Adds a new seed to the input corpus of the given fuzzing context - extended version.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param pvInput The pointer to the input buffer.
* @param cbInput Size of the input buffer.
* @param offMutStart Start offset at which a mutation can happen.
* @param cbMutRange Size of the range in bytes where a mutation can happen,
* use UINT64_MAX to allow mutations till the end of the input.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddEx(RTFUZZCTX hFuzzCtx, const void *pvInput, size_t cbInput,
uint64_t offMutStart, uint64_t cbMutRange);
/**
* Adds a new seed to the input corpus of the given fuzzing context from the given file.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param pszFilename The filename to load the seed from.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddFromFile(RTFUZZCTX hFuzzCtx, const char *pszFilename);
/**
* Adds a new seed to the input corpus of the given fuzzing context from the given file - extended version.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param pszFilename The filename to load the seed from.
* @param offMutStart Start offset at which a mutation can happen.
* @param cbMutRange Size of the range in bytes where a mutation can happen,
* use UINT64_MAX to allow mutations till the end of the input.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddFromFileEx(RTFUZZCTX hFuzzCtx, const char *pszFilename,
uint64_t offMutStart, uint64_t cbMutRange);
/**
* Adds a new seed to the input corpus of the given fuzzing context from the given VFS file.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param hVfsFile The VFS file handle to load the seed from.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddFromVfsFile(RTFUZZCTX hFuzzCtx, RTVFSFILE hVfsFile);
/**
* Adds a new seed to the input corpus of the given fuzzing context from the given VFS file - extended version.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param hVfsFile The VFS file handle to load the seed from.
* @param offMutStart Start offset at which a mutation can happen.
* @param cbMutRange Size of the range in bytes where a mutation can happen,
* use UINT64_MAX to allow mutations till the end of the input.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddFromVfsFileEx(RTFUZZCTX hFuzzCtx, RTVFSFILE hVfsFile,
uint64_t offMutStart, uint64_t cbMutRange);
/**
* Adds a new seed to the input corpus of the given fuzzing context from the given VFS I/O stream.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param hVfsIos The VFS I/O stream handle to load the seed from.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddFromVfsIoStrm(RTFUZZCTX hFuzzCtx, RTVFSIOSTREAM hVfsIos);
/**
* Adds a new seed to the input corpus of the given fuzzing context from the given VFS I/O stream - extended version.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param hVfsIos The VFS I/O stream handle to load the seed from.
* @param offMutStart Start offset at which a mutation can happen.
* @param cbMutRange Size of the range in bytes where a mutation can happen,
* use UINT64_MAX to allow mutations till the end of the input.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddFromVfsIoStrmEx(RTFUZZCTX hFuzzCtx, RTVFSIOSTREAM hVfsIos,
uint64_t offMutStart, uint64_t cbMutRange);
/**
* Adds new seeds to the input corpus of the given fuzzing context from the given directory.
*
* Will only process regular files, i.e. ignores directories, symbolic links, devices, fifos
* and such.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param pszDirPath The directory to load seeds from.
*/
RTDECL(int) RTFuzzCtxCorpusInputAddFromDirPath(RTFUZZCTX hFuzzCtx, const char *pszDirPath);
/**
* Restricts the maximum input size to generate by the fuzzing context.
*
* @returns IPRT status code
* @param hFuzzCtx The fuzzing context handle.
* @param cbMax Maximum input size in bytes.
*/
RTDECL(int) RTFuzzCtxCfgSetInputSeedMaximum(RTFUZZCTX hFuzzCtx, size_t cbMax);
/**
* Returns the maximum input size of the given fuzzing context.
*
* @returns Maximum input size generated in bytes.
* @param hFuzzCtx The fuzzing context handle.
*/
RTDECL(size_t) RTFuzzCtxCfgGetInputSeedMaximum(RTFUZZCTX hFuzzCtx);
/**
* Sets flags controlling the behavior of the fuzzing context.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param fFlags Flags controlling the fuzzing context, RTFUZZCTX_F_XXX.
*/
RTDECL(int) RTFuzzCtxCfgSetBehavioralFlags(RTFUZZCTX hFuzzCtx, uint32_t fFlags);
/**
* Returns the current set behavioral flags for the given fuzzing context.
*
* @returns Behavioral flags of the given fuzzing context.
* @param hFuzzCtx The fuzzing context handle.
*/
RTDECL(uint32_t) RTFuzzCfgGetBehavioralFlags(RTFUZZCTX hFuzzCtx);
/**
* Sets the temporary directory used by the fuzzing context.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param pszPathTmp The directory for the temporary state.
*/
RTDECL(int) RTFuzzCtxCfgSetTmpDirectory(RTFUZZCTX hFuzzCtx, const char *pszPathTmp);
/**
* Returns the current temporary directory.
*
* @returns Current temporary directory.
* @param hFuzzCtx The fuzzing context handle.
*/
RTDECL(const char *) RTFuzzCtxCfgGetTmpDirectory(RTFUZZCTX hFuzzCtx);
/**
* Sets the range in which a particular input can get mutated.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param offStart Start offset at which a mutation can happen.
* @param cbRange Size of the range in bytes where a mutation can happen,
* use UINT64_MAX to allow mutations till the end of the input.
*/
RTDECL(int) RTFuzzCtxCfgSetMutationRange(RTFUZZCTX hFuzzCtx, uint64_t offStart, uint64_t cbRange);
/**
* Reseeds the PRNG of the given fuzzing context.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param uSeed The new seed.
*/
RTDECL(int) RTFuzzCtxReseed(RTFUZZCTX hFuzzCtx, uint64_t uSeed);
/**
* Generates a new input from the given fuzzing context and returns it.
*
* @returns IPRT status code.
* @param hFuzzCtx The fuzzing context handle.
* @param phFuzzInput Where to store the handle to the fuzzed input on success.
*/
RTDECL(int) RTFuzzCtxInputGenerate(RTFUZZCTX hFuzzCtx, PRTFUZZINPUT phFuzzInput);
/**
* Retains a reference to the given fuzzing input handle.
*
* @returns New reference count on success.
* @param hFuzzInput The fuzzing input handle.
*/
RTDECL(uint32_t) RTFuzzInputRetain(RTFUZZINPUT hFuzzInput);
/**
* Releases a reference from the given fuzzing input handle, destroying it when reaching 0.
*
* @returns New reference count on success, 0 if the fuzzing input got destroyed.
* @param hFuzzInput The fuzzing input handle.
*/
RTDECL(uint32_t) RTFuzzInputRelease(RTFUZZINPUT hFuzzInput);
/**
* Queries the data pointer and size of the given fuzzed input blob.
*
* @returns IPRT status code
* @param hFuzzInput The fuzzing input handle.
* @param ppv Where to store the pointer to the input data on success.
* @param pcb Where to store the size of the input data on success.
*/
RTDECL(int) RTFuzzInputQueryBlobData(RTFUZZINPUT hFuzzInput, void **ppv, size_t *pcb);
/**
* Processes the given data stream for a streamed fuzzing context.
*
* @returns IPRT status code.
* @param hFuzzInput The fuzzing input handle.
* @param pvBuf The data buffer.
* @param cbBuf Size of the buffer.
*/
RTDECL(int) RTFuzzInputMutateStreamData(RTFUZZINPUT hFuzzInput, void *pvBuf, size_t cbBuf);
/**
* Queries the string of the MD5 digest for the given fuzzed input.
*
* @returns IPRT status code.
* @retval VERR_BUFFER_OVERFLOW if the size of the string buffer is not sufficient.
* @param hFuzzInput The fuzzing input handle.
* @param pszDigest Where to store the digest string and a closing terminator.
* @param cchDigest Size of the string buffer in characters (including the zero terminator).
*/
RTDECL(int) RTFuzzInputQueryDigestString(RTFUZZINPUT hFuzzInput, char *pszDigest, size_t cchDigest);
/**
* Writes the given fuzzing input to the given file.
*
* @returns IPRT status code.
* @param hFuzzInput The fuzzing input handle.
* @param pszFilename The filename to store the input to.
*/
RTDECL(int) RTFuzzInputWriteToFile(RTFUZZINPUT hFuzzInput, const char *pszFilename);
/**
* Adds the given fuzzed input to the input corpus of the owning context.
*
* @returns IPRT status code.
* @retval VERR_ALREADY_EXISTS if the input exists already.
* @param hFuzzInput The fuzzing input handle.
*/
RTDECL(int) RTFuzzInputAddToCtxCorpus(RTFUZZINPUT hFuzzInput);
/**
* Removes the given fuzzed input from the input corpus of the owning context.
*
* @returns IPRT status code.
* @retval VERR_NOT_FOUND if the input is not part of the corpus.
* @param hFuzzInput The fuzzing input handle.
*/
RTDECL(int) RTFuzzInputRemoveFromCtxCorpus(RTFUZZINPUT hFuzzInput);
/**
* Creates a fuzzing config from the given VFS file handle.
*
* @returns IPRT status code.
* @param phFuzzCfg Where to store the handle to the fuzzing config on success.
* @param hVfsFile The VFS file to use (retained).
* @param pErrInfo Where to store extended error info. Optional.
*/
RTDECL(int) RTFuzzCfgCreateFromVfsFile(PRTFUZZCFG phFuzzCfg, RTVFSFILE hVfsFile, PRTERRINFO pErrInfo);
/**
* Creates a fuzzing config from the given file path.
*
* @returns IPRT status code.
* @param phFuzzCfg Where to store the handle to the fuzzing config on success.
* @param pszFilename Filename to load the config from.
* @param pErrInfo Where to store extended error info. Optional.
*/
RTDECL(int) RTFuzzCfgCreateFromFile(PRTFUZZCFG phFuzzCfg, const char *pszFilename, PRTERRINFO pErrInfo);
/**
* Retains a reference to the given fuzzing config.
*
* @returns New reference count on success.
* @param hFuzzCfg Handle of the fuzzing config.
*/
RTDECL(uint32_t) RTFuzzCfgRetain(RTFUZZCFG hFuzzCfg);
/**
* Releases a reference from the given fuzzing config, destroying it when reaching 0.
*
* @returns New reference count on success, 0 if the fuzzing config got destroyed.
* @param hFuzzCfg Handle of the fuzzing config.
*/
RTDECL(uint32_t) RTFuzzCfgRelease(RTFUZZCFG hFuzzCfg);
/**
* Imports the given fuzzing config into a previously created fuzzing context.
*
* @returns IPRT status code.
* @param hFuzzCfg Handle of the fuzzing config.
* @param hFuzzCtx Handle of the fuzzing context.
* @param fFlags Flags controlling what to import exactly, combination of RTFUZZCFG_IMPORT_F_XXX.
*/
RTDECL(int) RTFuzzCfgImport(RTFUZZCFG hFuzzCfg, RTFUZZCTX hFuzzCtx, uint32_t fFlags);
/**
* Queries the custom config for the controller of the fuzzing process.
*
* @returns IPRT status code.
* @param hFuzzCfg Handle of the fuzzing config.
* @param phVfsFile Where to store the handle of the VFS file containing the custom config.
*/
RTDECL(int) RTFuzzCfgQueryCustomCfg(RTFUZZCFG hFuzzCfg, PRTVFSFILE phVfsFile);
/**
* Creates a new fuzzed target recorder.
*
* @returns IPRT status code.
* @param phFuzzTgtRec Where to store the handle to the fuzzed target recorder on success.
* @param fRecFlags What to take into account when checking for equal states.
* Combination of RTFUZZTGT_REC_STATE_F_*
*/
RTDECL(int) RTFuzzTgtRecorderCreate(PRTFUZZTGTREC phFuzzTgtRec, uint32_t fRecFlags);
/**
* Retains a reference to the given fuzzed target recorder handle.
*
* @returns New reference count on success.
* @param hFuzzTgtRec The fuzzed target recorder handle.
*/
RTDECL(uint32_t) RTFuzzTgtRecorderRetain(RTFUZZTGTREC hFuzzTgtRec);
/**
* Releases a reference from the given fuzzed target recorder handle, destroying it when reaching 0.
*
* @returns New reference count on success, 0 if the fuzzed target recorder got destroyed.
* @param hFuzzTgtRec The fuzzed target recorder handle.
*/
RTDECL(uint32_t) RTFuzzTgtRecorderRelease(RTFUZZTGTREC hFuzzTgtRec);
/**
* Creates a new empty fuzzed target state.
*
* @returns IPRT status code.
* @param hFuzzTgtRec The fuzzed target recorder handle.
* @param phFuzzTgtState Where to store the handle to the fuzzed target state on success.
*/
RTDECL(int) RTFuzzTgtRecorderCreateNewState(RTFUZZTGTREC hFuzzTgtRec, PRTFUZZTGTSTATE phFuzzTgtState);
/**
* Retains a reference to the given fuzzed target state handle.
*
* @returns New reference count on success.
* @param hFuzzTgtState The fuzzed target state handle.
*/
RTDECL(uint32_t) RTFuzzTgtStateRetain(RTFUZZTGTSTATE hFuzzTgtState);
/**
* Releases a reference from the given fuzzed target state handle, destroying it when reaching 0.
*
* @returns New reference count on success, 0 if the fuzzed target recorder got destroyed.
* @param hFuzzTgtState The fuzzed target state handle.
*/
RTDECL(uint32_t) RTFuzzTgtStateRelease(RTFUZZTGTSTATE hFuzzTgtState);
/**
* Resets the given fuzzed target state to an empty state (keeping allocated memory).
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
*
* @note Useful when the state is not added to the recorded set to avoid allocating memory.
*/
RTDECL(int) RTFuzzTgtStateReset(RTFUZZTGTSTATE hFuzzTgtState);
/**
* Finalizes the given fuzzed target state, making it readonly.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
*/
RTDECL(int) RTFuzzTgtStateFinalize(RTFUZZTGTSTATE hFuzzTgtState);
/**
* Adds the given state to the set for the owning target recorder.
*
* @returns IPRT status code.
* @retval VERR_ALREADY_EXISTS if the state is already existing in the recorder set.
* @param hFuzzTgtState The fuzzed target state handle.
*
* @note This also finalizes the target state if not already done.
*/
RTDECL(int) RTFuzzTgtStateAddToRecorder(RTFUZZTGTSTATE hFuzzTgtState);
/**
* Appends the given stdout output to the given target state.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
* @param pvStdOut Pointer to the stdout data buffer.
* @param cbStdOut Size of the stdout data buffer in bytes.
*/
RTDECL(int) RTFuzzTgtStateAppendStdoutFromBuf(RTFUZZTGTSTATE hFuzzTgtState, const void *pvStdOut, size_t cbStdOut);
/**
* Appends the given stderr output to the given target state.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
* @param pvStdErr Pointer to the stderr data buffer.
* @param cbStdErr Size of the stderr data buffer in bytes.
*/
RTDECL(int) RTFuzzTgtStateAppendStderrFromBuf(RTFUZZTGTSTATE hFuzzTgtState, const void *pvStdErr, size_t cbStdErr);
/**
* Appends the given stdout output to the given target state, reading from the given pipe.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
* @param hPipe The stdout pipe to read the data from.
*/
RTDECL(int) RTFuzzTgtStateAppendStdoutFromPipe(RTFUZZTGTSTATE hFuzzTgtState, RTPIPE hPipe);
/**
* Appends the given stderr output to the given target state, reading from the given pipe.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
* @param hPipe The stdout pipe to read the data from.
*/
RTDECL(int) RTFuzzTgtStateAppendStderrFromPipe(RTFUZZTGTSTATE hFuzzTgtState, RTPIPE hPipe);
/**
* Adds the SanCov coverage information from the given file to the given target state.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
* @param pszFilename Filename of the coverage report.
*/
RTDECL(int) RTFuzzTgtStateAddSanCovReportFromFile(RTFUZZTGTSTATE hFuzzTgtState, const char *pszFilename);
/**
* Adds the given process status to the target state.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
* @param pProcSts The process status to add.
*/
RTDECL(int) RTFuzzTgtStateAddProcSts(RTFUZZTGTSTATE hFuzzTgtState, PCRTPROCSTATUS pProcSts);
/**
* Dumps the given target state to the given directory.
*
* @returns IPRT status code.
* @param hFuzzTgtState The fuzzed target state handle.
* @param pszDirPath The directory to dump to.
*/
RTDECL(int) RTFuzzTgtStateDumpToDir(RTFUZZTGTSTATE hFuzzTgtState, const char *pszDirPath);
/**
* Fuzzed binary input channel.
*/
typedef enum RTFUZZOBSINPUTCHAN
{
/** Invalid. */
RTFUZZOBSINPUTCHAN_INVALID = 0,
/** File input. */
RTFUZZOBSINPUTCHAN_FILE,
/** Input over stdin. */
RTFUZZOBSINPUTCHAN_STDIN,
/** The binary is a fuzzing aware client using the
* specified protocol over stdin/stdout. */
RTFUZZOBSINPUTCHAN_FUZZING_AWARE_CLIENT,
/** TCP server. */
RTFUZZOBSINPUTCHAN_TCP_SERVER,
/** TCP client. */
RTFUZZOBSINPUTCHAN_TCP_CLIENT,
/** UDP server. */
RTFUZZOBSINPUTCHAN_UDP_SERVER,
/** UDP client. */
RTFUZZOBSINPUTCHAN_UDP_CLIENT,
/** 32bit hack. */
RTFUZZOBSINPUTCHAN_32BIT_HACK = 0x7fffffff
} RTFUZZOBSINPUTCHAN;
/**
* Fuzzing observer statistics.
*/
typedef struct RTFUZZOBSSTATS
{
/** Number of fuzzed inputs per second. */
uint32_t cFuzzedInputsPerSec;
/** Number of overall fuzzed inputs. */
uint32_t cFuzzedInputs;
/** Number of observed hangs. */
uint32_t cFuzzedInputsHang;
/** Number of observed crashes. */
uint32_t cFuzzedInputsCrash;
} RTFUZZOBSSTATS;
/** Pointer to a fuzzing observer statistics record. */
typedef RTFUZZOBSSTATS *PRTFUZZOBSSTATS;
/**
* Creates a new fuzzing observer.
*
* @returns IPRT status code.
* @param phFuzzObs Where to store the fuzzing observer handle on success.
* @param enmType Fuzzing context data type.
* @param fTgtRecFlags Flags to pass to the target state recorder, see RTFuzzTgtRecorderCreate().
*/
RTDECL(int) RTFuzzObsCreate(PRTFUZZOBS phFuzzObs, RTFUZZCTXTYPE enmType, uint32_t fTgtRecFlags);
/**
* Destroys a previously created fuzzing observer.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
*/
RTDECL(int) RTFuzzObsDestroy(RTFUZZOBS hFuzzObs);
/**
* Queries the internal fuzzing context of the given observer.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param phFuzzCtx Where to store the handle to the fuzzing context on success.
*
* @note The fuzzing context handle should be released with RTFuzzCtxRelease() when not used anymore.
*/
RTDECL(int) RTFuzzObsQueryCtx(RTFUZZOBS hFuzzObs, PRTFUZZCTX phFuzzCtx);
/**
* Queries the current statistics for the given fuzzing observer.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param pStats Where to store the statistics to.
*/
RTDECL(int) RTFuzzObsQueryStats(RTFUZZOBS hFuzzObs, PRTFUZZOBSSTATS pStats);
/**
* Sets the temp directory for the given fuzzing observer.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param pszTmp The temp directory path.
*/
RTDECL(int) RTFuzzObsSetTmpDirectory(RTFUZZOBS hFuzzObs, const char *pszTmp);
/**
* Sets the directory to store results to.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param pszResults The path to store the results.
*/
RTDECL(int) RTFuzzObsSetResultDirectory(RTFUZZOBS hFuzzObs, const char *pszResults);
/**
* Sets the binary to run for each fuzzed input.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param pszBinary The binary path.
* @param enmInputChan The input channel to use.
*/
RTDECL(int) RTFuzzObsSetTestBinary(RTFUZZOBS hFuzzObs, const char *pszBinary, RTFUZZOBSINPUTCHAN enmInputChan);
/**
* Sets additional arguments to run the binary with.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param papszArgs Pointer to the array of arguments.
* @param cArgs Number of arguments.
*/
RTDECL(int) RTFuzzObsSetTestBinaryArgs(RTFUZZOBS hFuzzObs, const char * const *papszArgs, unsigned cArgs);
/**
* Sets an environment block to run the binary in.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param hEnv The environment block to set for the test binary.
* Use RTENV_DEFAULT for the default process environment or
* NULL for an empty environment.
*
* @note Upon successful return of this function the observer has taken ownership over the
* environment block and can alter it in unexpected ways. It also destroys the environment
* block when the observer gets destroyed. So don't touch the environment block after
* calling this function.
*/
RTDECL(int) RTFuzzObsSetTestBinaryEnv(RTFUZZOBS hFuzzObs, RTENV hEnv);
/**
* Makes the observer aware of any configured sanitizers for the test binary.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param fSanitizers Bitmask of compiled and enabled sanitiziers in the
* target binary.
*/
RTDECL(int) RTFuzzObsSetTestBinarySanitizers(RTFUZZOBS hFuzzObs, uint32_t fSanitizers);
/**
* Sets maximum timeout until a process is considered hung and killed.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param msTimeoutMax The maximum number of milliseconds to wait until the process
* is considered hung.
*/
RTDECL(int) RTFuzzObsSetTestBinaryTimeout(RTFUZZOBS hFuzzObs, RTMSINTERVAL msTimeoutMax);
/**
* Starts fuzzing the set binary.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
* @param cProcs Number of processes to run simulteanously,
* 0 will create as many processes as there are CPUs available.
*/
RTDECL(int) RTFuzzObsExecStart(RTFUZZOBS hFuzzObs, uint32_t cProcs);
/**
* Stops the fuzzing process.
*
* @returns IPRT status code.
* @param hFuzzObs The fuzzing observer handle.
*/
RTDECL(int) RTFuzzObsExecStop(RTFUZZOBS hFuzzObs);
/**
* A fuzzing master program.
*
* @returns Program exit code.
*
* @param cArgs The number of arguments.
* @param papszArgs The argument vector. (Note that this may be
* reordered, so the memory must be writable.)
*/
RTR3DECL(RTEXITCODE) RTFuzzCmdMaster(unsigned cArgs, char **papszArgs);
/**
* Client input consumption callback.
*
* @returns IPRT status code.
* @retval VINF_SUCCESS the fuzzed code accepted the input.
* @retval VERR_* the client rejected the input while parsing it.
* @param pvBuf The buffer containing the input data.
* @param cbBuf Size of the buffer in bytes.
* @param pvUser Opaque user data.
*/
typedef DECLCALLBACKTYPE(int, FNFUZZCLIENTCONSUME,(const void *pvBuf, size_t cbBuf, void *pvUser));
/** Pointer to a client consumption callback. */
typedef FNFUZZCLIENTCONSUME *PFNFUZZCLIENTCONSUME;
/**
* A fuzzing client program for more efficient fuzzing.
*
* @returns Program exit code.
*
* @param cArgs The number of arguments.
* @param papszArgs The argument vector. (Note that this may be
* reordered, so the memory must be writable.)
* @param pfnConsume Input data consumption callback.
* @param pvUser Opaque user data to pass to the callback.
*/
RTR3DECL(RTEXITCODE) RTFuzzCmdFuzzingClient(unsigned cArgs, char **papszArgs, PFNFUZZCLIENTCONSUME pfnConsume, void *pvUser);
/** @} */
RT_C_DECLS_END
#endif /* !IPRT_INCLUDED_fuzz_h */