summaryrefslogtreecommitdiffstats
path: root/include/iprt/fuzz.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/iprt/fuzz.h501
1 files changed, 501 insertions, 0 deletions
diff --git a/include/iprt/fuzz.h b/include/iprt/fuzz.h
new file mode 100644
index 00000000..c6f585c2
--- /dev/null
+++ b/include/iprt/fuzz.h
@@ -0,0 +1,501 @@
+/** @file
+ * IPRT - Fuzzing framework
+ */
+
+/*
+ * Copyright (C) 2018-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE 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.
+ */
+
+#ifndef IPRT_INCLUDED_fuzz_h
+#define IPRT_INCLUDED_fuzz_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.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)
+
+
+/** 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)
+
+
+/** @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)
+/** @} */
+
+/**
+ * Creates a new fuzzing context.
+ *
+ * @returns IPRT status code.
+ * @param phFuzzCtx Where to store the handle to the fuzzing context on success.
+ */
+RTDECL(int) RTFuzzCtxCreate(PRTFUZZCTX phFuzzCtx);
+
+/**
+ * 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 pvState The pointer to the fuzzing state.
+ * @param cbState Size of the state buffer in bytes.
+ */
+RTDECL(int) RTFuzzCtxCreateFromState(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);
+
+/**
+ * Exports the given fuzzing context state.
+ *
+ * @returns IPRT statuse code
+ * @param hFuzzCtx The fuzzing context to export.
+ * @param ppvState Where to store the buffer of the state on success, free with RTMemFree().
+ * @param pcbState Where to store the size of the context on success.
+ */
+RTDECL(int) RTFuzzCtxStateExport(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 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 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 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);
+
+/**
+ * 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);
+
+/**
+ * Mutates a raw buffer.
+ *
+ * @returns IPRT status code.
+ * @param hFuzzCtx The fuzzing context handle.
+ * @param pvBuf Pointer to the buffer to mutate.
+ * @param cbBuf Size of the buffer iny bytes to mutate.
+ * @param phFuzzInput Where to store the handle to the fuzzed input on success.
+ */
+RTDECL(int) RTFuzzCtxMutateBuffer(RTFUZZCTX hFuzzCtx, void *pvBuf, size_t cbBuf,
+ 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 reaaching 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 fuzzing input.
+ *
+ * @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) RTFuzzInputQueryData(RTFUZZINPUT hFuzzInput, void **ppv, size_t *pcb);
+
+/**
+ * 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);
+
+
+/**
+ * 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.
+ */
+RTDECL(int) RTFuzzObsCreate(PRTFUZZOBS phFuzzObs);
+
+/**
+ * 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);
+
+/**
+ * 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 DECLCALLBACK(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 */
+