VirtualBox

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

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

Runtime/RTFuzz: Some updates, add a mode where the client is aware of being fuzzed for improved efficiency. The input data is fuzzed in the client and fed to the consumer until the program crashes upon the master can reconstruct the input causing the crash because we work with deterministic random number generators. This eliminates the overhead of constantly spawning new client processes.

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

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