VirtualBox

source: vbox/trunk/include/iprt/fuzz.h@ 77482

Last change on this file since 77482 was 77482, checked in by vboxsync, 6 years ago

Runtime/fuzz: Rewriting the core fuzzed input generator.

The new implementation stores only changes between mutations and not the
complete input. This saves memory (at the cost of a bit of increased complexity
when generating the input) and allows to generate mutations when no initial corpus
data is available which is useful when trying to fuzz data streams like network connections.

There are two modes when creating a new fuzzing context:

  • BLOB is used for input data like files where an initial corpus is available
  • STREAM is used for data streams like network connections
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.6 KB
Line 
1/** @file
2 * IPRT - Fuzzing framework
3 */
4
5/*
6 * Copyright (C) 2018-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.215389.xyz. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_fuzz_h
27#define IPRT_INCLUDED_fuzz_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
34
35RT_C_DECLS_BEGIN
36
37/** @defgroup grp_rt_fuzz RTFuzz - Data fuzzing framework
38 * @ingroup grp_rt
39 * @sa grp_rt_test
40 * @{
41 */
42
43/** A fuzzer context handle. */
44typedef struct RTFUZZCTXINT *RTFUZZCTX;
45/** Pointer to a fuzzer context handle. */
46typedef RTFUZZCTX *PRTFUZZCTX;
47/** NIL fuzzer context handle. */
48#define NIL_RTFUZZCTX ((RTFUZZCTX)~(uintptr_t)0)
49/** A fuzzer input handle. */
50typedef struct RTFUZZINPUTINT *RTFUZZINPUT;
51/** Pointer to a fuzzer input handle. */
52typedef RTFUZZINPUT *PRTFUZZINPUT;
53/** NIL fuzzer input handle. */
54#define NIL_RTFUZZINPUT ((RTFUZZINPUT)~(uintptr_t)0)
55
56
57/** Fuzzing observer handle. */
58typedef struct RTFUZZOBSINT *RTFUZZOBS;
59/** Pointer to a fuzzing observer handle. */
60typedef RTFUZZOBS *PRTFUZZOBS;
61/** NIL fuzzing observer handle. */
62#define NIL_RTFUZZOBS ((RTFUZZOBS)~(uintptr_t)0)
63
64
65/**
66 * Fuzzing context type.
67 */
68typedef enum RTFUZZCTXTYPE
69{
70 /** Invalid type. */
71 RTFUZZCTXTYPE_INVALID = 0,
72 /** Original input data is a single binary large object (BLOB), from a file or similar. */
73 RTFUZZCTXTYPE_BLOB,
74 /** Original input data is from a data stream like a network connection. */
75 RTFUZZCTXTYPE_STREAM,
76 /** 32bit hack. */
77 RTFUZZCTXTYPE_32BIT_HACK = 0x7fffffff
78} RTFUZZCTXTYPE;
79
80/** @name RTFUZZCTX_F_XXX - Flags for RTFuzzCtxCfgSetBehavioralFlags
81 * @{ */
82/** Adds all generated inputs automatically to the input corpus for the owning context. */
83#define RTFUZZCTX_F_BEHAVIORAL_ADD_INPUT_AUTOMATICALLY_TO_CORPUS RT_BIT_32(0)
84/** All valid behavioral modification flags. */
85#define RTFUZZCTX_F_BEHAVIORAL_VALID (RTFUZZCTX_F_BEHAVIORAL_ADD_INPUT_AUTOMATICALLY_TO_CORPUS)
86/** @} */
87
88/**
89 * Creates a new fuzzing context.
90 *
91 * @returns IPRT status code.
92 * @param phFuzzCtx Where to store the handle to the fuzzing context on success.
93 * @param enmType Fuzzing context data type.
94 */
95RTDECL(int) RTFuzzCtxCreate(PRTFUZZCTX phFuzzCtx, RTFUZZCTXTYPE enmType);
96
97/**
98 * Creates a new fuzzing context from the given state.
99 *
100 * @returns IPRT status code.
101 * @param phFuzzCtx Where to store the handle to the fuzzing context on success.
102 * @param pvState The pointer to the fuzzing state.
103 * @param cbState Size of the state buffer in bytes.
104 */
105RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState);
106
107/**
108 * Creates a new fuzzing context loading the state from the given file.
109 *
110 * @returns IPRT status code.
111 * @param phFuzzCtx Where to store the handle to the fuzzing context on success.
112 * @param pszFilename File to load the fuzzing context from.
113 */
114RTDECL(int) RTFuzzCtxCreateFromStateFile(PRTFUZZCTX phFuzzCtx, const char *pszFilename);
115
116/**
117 * Retains a reference to the given fuzzing context.
118 *
119 * @returns New reference count on success.
120 * @param hFuzzCtx Handle of the fuzzing context.
121 */
122RTDECL(uint32_t) RTFuzzCtxRetain(RTFUZZCTX hFuzzCtx);
123
124/**
125 * Releases a reference from the given fuzzing context, destroying it when reaching 0.
126 *
127 * @returns New reference count on success, 0 if the fuzzing context got destroyed.
128 * @param hFuzzCtx Handle of the fuzzing context.
129 */
130RTDECL(uint32_t) RTFuzzCtxRelease(RTFUZZCTX hFuzzCtx);
131
132/**
133 * Exports the given fuzzing context state.
134 *
135 * @returns IPRT statuse code
136 * @param hFuzzCtx The fuzzing context to export.
137 * @param ppvState Where to store the buffer of the state on success, free with RTMemFree().
138 * @param pcbState Where to store the size of the context on success.
139 */
140RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState);
141
142/**
143 * Exports the given fuzzing context state to the given file.
144 *
145 * @returns IPRT status code.
146 * @param hFuzzCtx The fuzzing context to export.
147 * @param pszFilename The file to save the state to.
148 */
149RTDECL(int) RTFuzzCtxStateExportToFile(RTFUZZCTX hFuzzCtx, const char *pszFilename);
150
151/**
152 * Adds a new seed to the input corpus of the given fuzzing context.
153 *
154 * @returns IPRT status code.
155 * @param hFuzzCtx The fuzzing context handle.
156 * @param pvInput The pointer to the input buffer.
157 * @param cbInput Size of the input buffer.
158 */
159RTDECL(int) RTFuzzCtxCorpusInputAdd(RTFUZZCTX hFuzzCtx, const void *pvInput, size_t cbInput);
160
161/**
162 * Adds a new seed to the input corpus of the given fuzzing context from the given file.
163 *
164 * @returns IPRT status code.
165 * @param hFuzzCtx The fuzzing context handle.
166 * @param pszFilename The filename to load the seed from.
167 */
168RTDECL(int) RTFuzzCtxCorpusInputAddFromFile(RTFUZZCTX hFuzzCtx, const char *pszFilename);
169
170/**
171 * Adds a new seed to the input corpus of the given fuzzing context from the given VFS file.
172 *
173 * @returns IPRT status code.
174 * @param hFuzzCtx The fuzzing context handle.
175 * @param hVfsFile The VFS file handle to load the seed from.
176 */
177RTDECL(int) RTFuzzCtxCorpusInputAddFromVfsFile(RTFUZZCTX hFuzzCtx, RTVFSFILE hVfsFile);
178
179/**
180 * Adds new seeds to the input corpus of the given fuzzing context from the given directory.
181 *
182 * Will only process regular files, i.e. ignores directories, symbolic links, devices, fifos
183 * and such.
184 *
185 * @returns IPRT status code.
186 * @param hFuzzCtx The fuzzing context handle.
187 * @param pszDirPath The directory to load seeds from.
188 */
189RTDECL(int) RTFuzzCtxCorpusInputAddFromDirPath(RTFUZZCTX hFuzzCtx, const char *pszDirPath);
190
191/**
192 * Restricts the maximum input size to generate by the fuzzing context.
193 *
194 * @returns IPRT status code
195 * @param hFuzzCtx The fuzzing context handle.
196 * @param cbMax Maximum input size in bytes.
197 */
198RTDECL(int) RTFuzzCtxCfgSetInputSeedMaximum(RTFUZZCTX hFuzzCtx, size_t cbMax);
199
200/**
201 * Returns the maximum input size of the given fuzzing context.
202 *
203 * @returns Maximum input size generated in bytes.
204 * @param hFuzzCtx The fuzzing context handle.
205 */
206RTDECL(size_t) RTFuzzCtxCfgGetInputSeedMaximum(RTFUZZCTX hFuzzCtx);
207
208/**
209 * Sets flags controlling the behavior of the fuzzing context.
210 *
211 * @returns IPRT status code.
212 * @param hFuzzCtx The fuzzing context handle.
213 * @param fFlags Flags controlling the fuzzing context, RTFUZZCTX_F_XXX.
214 */
215RTDECL(int) RTFuzzCtxCfgSetBehavioralFlags(RTFUZZCTX hFuzzCtx, uint32_t fFlags);
216
217/**
218 * Returns the current set behavioral flags for the given fuzzing context.
219 *
220 * @returns Behavioral flags of the given fuzzing context.
221 * @param hFuzzCtx The fuzzing context handle.
222 */
223RTDECL(uint32_t) RTFuzzCfgGetBehavioralFlags(RTFUZZCTX hFuzzCtx);
224
225/**
226 * Sets the temporary directory used by the fuzzing context.
227 *
228 * @returns IPRT status code.
229 * @param hFuzzCtx The fuzzing context handle.
230 * @param pszPathTmp The directory for the temporary state.
231 */
232RTDECL(int) RTFuzzCtxCfgSetTmpDirectory(RTFUZZCTX hFuzzCtx, const char *pszPathTmp);
233
234/**
235 * Returns the current temporary directory.
236 *
237 * @returns Current temporary directory.
238 * @param hFuzzCtx The fuzzing context handle.
239 */
240RTDECL(const char *) RTFuzzCtxCfgGetTmpDirectory(RTFUZZCTX hFuzzCtx);
241
242/**
243 * Reseeds the PRNG of the given fuzzing context.
244 *
245 * @returns IPRT status code.
246 * @param hFuzzCtx The fuzzing context handle.
247 * @param uSeed The new seed.
248 */
249RTDECL(int) RTFuzzCtxReseed(RTFUZZCTX hFuzzCtx, uint64_t uSeed);
250
251/**
252 * Generates a new input from the given fuzzing context and returns it.
253 *
254 * @returns IPRT status code.
255 * @param hFuzzCtx The fuzzing context handle.
256 * @param phFuzzInput Where to store the handle to the fuzzed input on success.
257 */
258RTDECL(int) RTFuzzCtxInputGenerate(RTFUZZCTX hFuzzCtx, PRTFUZZINPUT phFuzzInput);
259
260
261/**
262 * Retains a reference to the given fuzzing input handle.
263 *
264 * @returns New reference count on success.
265 * @param hFuzzInput The fuzzing input handle.
266 */
267RTDECL(uint32_t) RTFuzzInputRetain(RTFUZZINPUT hFuzzInput);
268
269/**
270 * Releases a reference from the given fuzzing input handle, destroying it when reaaching 0.
271 *
272 * @returns New reference count on success, 0 if the fuzzing input got destroyed.
273 * @param hFuzzInput The fuzzing input handle.
274 */
275RTDECL(uint32_t) RTFuzzInputRelease(RTFUZZINPUT hFuzzInput);
276
277/**
278 * Queries the data pointer and size of the given fuzzed input blob.
279 *
280 * @returns IPRT status code
281 * @param hFuzzInput The fuzzing input handle.
282 * @param ppv Where to store the pointer to the input data on success.
283 * @param pcb Where to store the size of the input data on success.
284 */
285RTDECL(int) RTFuzzInputQueryBlobData(RTFUZZINPUT hFuzzInput, void **ppv, size_t *pcb);
286
287/**
288 * Processes the given data stream for a streamed fuzzing context.
289 *
290 * @returns IPRT status code.
291 * @param hFuzzInput The fuzzing input handle.
292 * @param pvBuf The data buffer.
293 * @param cbBuf Size of the buffer.
294 */
295RTDECL(int) RTFuzzInputMutateStreamData(RTFUZZINPUT hFuzzInput, void *pvBuf, size_t cbBuf);
296
297/**
298 * Queries the string of the MD5 digest for the given fuzzed input.
299 *
300 * @returns IPRT status code.
301 * @retval VERR_BUFFER_OVERFLOW if the size of the string buffer is not sufficient.
302 * @param hFuzzInput The fuzzing input handle.
303 * @param pszDigest Where to store the digest string and a closing terminator.
304 * @param cchDigest Size of the string buffer in characters (including the zero terminator).
305 */
306RTDECL(int) RTFuzzInputQueryDigestString(RTFUZZINPUT hFuzzInput, char *pszDigest, size_t cchDigest);
307
308/**
309 * Writes the given fuzzing input to the given file.
310 *
311 * @returns IPRT status code.
312 * @param hFuzzInput The fuzzing input handle.
313 * @param pszFilename The filename to store the input to.
314 */
315RTDECL(int) RTFuzzInputWriteToFile(RTFUZZINPUT hFuzzInput, const char *pszFilename);
316
317/**
318 * Adds the given fuzzed input to the input corpus of the owning context.
319 *
320 * @returns IPRT status code.
321 * @retval VERR_ALREADY_EXISTS if the input exists already.
322 * @param hFuzzInput The fuzzing input handle.
323 */
324RTDECL(int) RTFuzzInputAddToCtxCorpus(RTFUZZINPUT hFuzzInput);
325
326/**
327 * Removes the given fuzzed input from the input corpus of the owning context.
328 *
329 * @returns IPRT status code.
330 * @retval VERR_NOT_FOUND if the input is not part of the corpus.
331 * @param hFuzzInput The fuzzing input handle.
332 */
333RTDECL(int) RTFuzzInputRemoveFromCtxCorpus(RTFUZZINPUT hFuzzInput);
334
335
336/**
337 * Fuzzed binary input channel.
338 */
339typedef enum RTFUZZOBSINPUTCHAN
340{
341 /** Invalid. */
342 RTFUZZOBSINPUTCHAN_INVALID = 0,
343 /** File input. */
344 RTFUZZOBSINPUTCHAN_FILE,
345 /** Input over stdin. */
346 RTFUZZOBSINPUTCHAN_STDIN,
347 /** The binary is a fuzzing aware client using the
348 * specified protocol over stdin/stdout. */
349 RTFUZZOBSINPUTCHAN_FUZZING_AWARE_CLIENT,
350 /** TCP server. */
351 RTFUZZOBSINPUTCHAN_TCP_SERVER,
352 /** TCP client. */
353 RTFUZZOBSINPUTCHAN_TCP_CLIENT,
354 /** UDP server. */
355 RTFUZZOBSINPUTCHAN_UDP_SERVER,
356 /** UDP client. */
357 RTFUZZOBSINPUTCHAN_UDP_CLIENT,
358 /** 32bit hack. */
359 RTFUZZOBSINPUTCHAN_32BIT_HACK = 0x7fffffff
360} RTFUZZOBSINPUTCHAN;
361
362/**
363 * Fuzzing observer statistics.
364 */
365typedef struct RTFUZZOBSSTATS
366{
367 /** Number of fuzzed inputs per second. */
368 uint32_t cFuzzedInputsPerSec;
369 /** Number of overall fuzzed inputs. */
370 uint32_t cFuzzedInputs;
371 /** Number of observed hangs. */
372 uint32_t cFuzzedInputsHang;
373 /** Number of observed crashes. */
374 uint32_t cFuzzedInputsCrash;
375} RTFUZZOBSSTATS;
376/** Pointer to a fuzzing observer statistics record. */
377typedef RTFUZZOBSSTATS *PRTFUZZOBSSTATS;
378
379/**
380 * Creates a new fuzzing observer.
381 *
382 * @returns IPRT status code.
383 * @param phFuzzObs Where to store the fuzzing observer handle on success.
384 * @param enmType Fuzzing context data type.
385 */
386RTDECL(int) RTFuzzObsCreate(PRTFUZZOBS phFuzzObs, RTFUZZCTXTYPE enmType);
387
388/**
389 * Destroys a previously created fuzzing observer.
390 *
391 * @returns IPRT status code.
392 * @param hFuzzObs The fuzzing observer handle.
393 */
394RTDECL(int) RTFuzzObsDestroy(RTFUZZOBS hFuzzObs);
395
396/**
397 * Queries the internal fuzzing context of the given observer.
398 *
399 * @returns IPRT status code.
400 * @param hFuzzObs The fuzzing observer handle.
401 * @param phFuzzCtx Where to store the handle to the fuzzing context on success.
402 *
403 * @note The fuzzing context handle should be released with RTFuzzCtxRelease() when not used anymore.
404 */
405RTDECL(int) RTFuzzObsQueryCtx(RTFUZZOBS hFuzzObs, PRTFUZZCTX phFuzzCtx);
406
407/**
408 * Queries the current statistics for the given fuzzing observer.
409 *
410 * @returns IPRT status code.
411 * @param hFuzzObs The fuzzing observer handle.
412 * @param pStats Where to store the statistics to.
413 */
414RTDECL(int) RTFuzzObsQueryStats(RTFUZZOBS hFuzzObs, PRTFUZZOBSSTATS pStats);
415
416/**
417 * Sets the temp directory for the given fuzzing observer.
418 *
419 * @returns IPRT status code.
420 * @param hFuzzObs The fuzzing observer handle.
421 * @param pszTmp The temp directory path.
422 */
423RTDECL(int) RTFuzzObsSetTmpDirectory(RTFUZZOBS hFuzzObs, const char *pszTmp);
424
425/**
426 * Sets the directory to store results to.
427 *
428 * @returns IPRT status code.
429 * @param hFuzzObs The fuzzing observer handle.
430 * @param pszResults The path to store the results.
431 */
432RTDECL(int) RTFuzzObsSetResultDirectory(RTFUZZOBS hFuzzObs, const char *pszResults);
433
434/**
435 * Sets the binary to run for each fuzzed input.
436 *
437 * @returns IPRT status code.
438 * @param hFuzzObs The fuzzing observer handle.
439 * @param pszBinary The binary path.
440 * @param enmInputChan The input channel to use.
441 */
442RTDECL(int) RTFuzzObsSetTestBinary(RTFUZZOBS hFuzzObs, const char *pszBinary, RTFUZZOBSINPUTCHAN enmInputChan);
443
444/**
445 * Sets additional arguments to run the binary with.
446 *
447 * @returns IPRT status code.
448 * @param hFuzzObs The fuzzing observer handle.
449 * @param papszArgs Pointer to the array of arguments.
450 * @param cArgs Number of arguments.
451 */
452RTDECL(int) RTFuzzObsSetTestBinaryArgs(RTFUZZOBS hFuzzObs, const char * const *papszArgs, unsigned cArgs);
453
454/**
455 * Starts fuzzing the set binary.
456 *
457 * @returns IPRT status code.
458 * @param hFuzzObs The fuzzing observer handle.
459 * @param cProcs Number of processes to run simulteanously,
460 * 0 will create as many processes as there are CPUs available.
461 */
462RTDECL(int) RTFuzzObsExecStart(RTFUZZOBS hFuzzObs, uint32_t cProcs);
463
464/**
465 * Stops the fuzzing process.
466 *
467 * @returns IPRT status code.
468 * @param hFuzzObs The fuzzing observer handle.
469 */
470RTDECL(int) RTFuzzObsExecStop(RTFUZZOBS hFuzzObs);
471
472
473/**
474 * A fuzzing master program.
475 *
476 * @returns Program exit code.
477 *
478 * @param cArgs The number of arguments.
479 * @param papszArgs The argument vector. (Note that this may be
480 * reordered, so the memory must be writable.)
481 */
482RTR3DECL(RTEXITCODE) RTFuzzCmdMaster(unsigned cArgs, char **papszArgs);
483
484
485/**
486 * Client input consumption callback.
487 *
488 * @returns IPRT status code.
489 * @retval VINF_SUCCESS the fuzzed code accepted the input.
490 * @retval VERR_* the client rejected the input while parsing it.
491 * @param pvBuf The buffer containing the input data.
492 * @param cbBuf Size of the buffer in bytes.
493 * @param pvUser Opaque user data.
494 */
495typedef DECLCALLBACK(int) FNFUZZCLIENTCONSUME(const void *pvBuf, size_t cbBuf, void *pvUser);
496/** Pointer to a client consumption callback. */
497typedef FNFUZZCLIENTCONSUME *PFNFUZZCLIENTCONSUME;
498
499/**
500 * A fuzzing client program for more efficient fuzzing.
501 *
502 * @returns Program exit code.
503 *
504 * @param cArgs The number of arguments.
505 * @param papszArgs The argument vector. (Note that this may be
506 * reordered, so the memory must be writable.)
507 * @param pfnConsume Input data consumption callback.
508 * @param pvUser Opaque user data to pass to the callback.
509 */
510RTR3DECL(RTEXITCODE) RTFuzzCmdFuzzingClient(unsigned cArgs, char **papszArgs, PFNFUZZCLIENTCONSUME pfnConsume, void *pvUser);
511/** @} */
512
513RT_C_DECLS_END
514
515#endif /* !IPRT_INCLUDED_fuzz_h */
516
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette