Changeset 77509 in vbox
- Timestamp:
- Feb 28, 2019 7:14:03 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129108
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/fuzz.h
r77482 r77509 78 78 } RTFUZZCTXTYPE; 79 79 80 80 81 /** @name RTFUZZCTX_F_XXX - Flags for RTFuzzCtxCfgSetBehavioralFlags 81 82 * @{ */ … … 86 87 /** @} */ 87 88 89 90 /** 91 * Fuzzing context state export callback. 92 * 93 * @returns IPRT status code. 94 * @param hFuzzCtx Handle of the fuzzing context. 95 * @param pvBuf The data to write. 96 * @param cbWrite Number of bytes to write. 97 * @param pvUser Opaque user data passed in RTFuzzCtxStateExport(). 98 */ 99 typedef DECLCALLBACK(int) FNRTFUZZCTXEXPORT(RTFUZZCTX hFuzzCtx, const void *pvBuf, size_t cbWrite, void *pvUser); 100 /** Pointer to a fuzzing context state export callback. */ 101 typedef FNRTFUZZCTXEXPORT *PFNRTFUZZCTXEXPORT; 102 103 /** 104 * Fuzzing context state import callback. 105 * 106 * @returns IPRT status code. 107 * @param hFuzzCtx Handle of the fuzzing context. 108 * @param pvBuf Where to store the read data. 109 * @param cbRead Number of bytes to read. 110 * @param pcbRead Where to store the amount of data written, optional. 111 * @param pvUser Opaque user data passed in RTFuzzCtxCreateFromState(). 112 */ 113 typedef DECLCALLBACK(int) FNRTFUZZCTXIMPORT(RTFUZZCTX hFuzzCtx, void *pvBuf, size_t cbRead, size_t *pcbRead, void *pvUser); 114 /** Pointer to a fuzzing context state export callback. */ 115 typedef FNRTFUZZCTXIMPORT *PFNRTFUZZCTXIMPORT; 116 117 88 118 /** 89 119 * Creates a new fuzzing context. … … 100 130 * @returns IPRT status code. 101 131 * @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 */ 105 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState); 132 * @param pfnImport State import callback. 133 * @param pvUser Opaque user data to pass to the callback. 134 */ 135 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, PFNRTFUZZCTXIMPORT pfnImport, void *pvUser); 136 137 /** 138 * Creates a new fuzzing context loading the state from the given memory buffer. 139 * 140 * @returns IPRT status code. 141 * @param phFuzzCtx Where to store the handle to the fuzzing context on success. 142 * @param pvState Pointer to the memory containing the state. 143 * @param cbState Size of the state buffer. 144 */ 145 RTDECL(int) RTFuzzCtxCreateFromStateMem(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState); 106 146 107 147 /** … … 135 175 * @returns IPRT statuse code 136 176 * @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 */ 140 RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState); 177 * @param pfnExport Export callback. 178 * @param pvUser Opaque user data to pass to the callback. 179 */ 180 RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, PFNRTFUZZCTXEXPORT pfnExport, void *pvUser); 181 182 /** 183 * Exports the given fuzzing context state to memory allocating the buffer. 184 * 185 * @returns IPRT status code. 186 * @param hFuzzCtx The fuzzing context to export. 187 * @param ppvState Where to store the pointer to the memory containing state on success. 188 * Free with RTMemFree(). 189 * @param pcbState Where to store the size of the state in bytes. 190 */ 191 RTDECL(int) RTFuzzCtxStateExportToMem(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState); 141 192 142 193 /** -
trunk/include/iprt/mangling.h
r77482 r77509 1037 1037 # define RTFuzzCtxCreateFromState RT_MANGLER(RTFuzzCtxCreateFromState) 1038 1038 # define RTFuzzCtxCreateFromStateFile RT_MANGLER(RTFuzzCtxCreateFromStateFile) 1039 # define RTFuzzCtxCreateFromStateMem RT_MANGLER(RTFuzzCtxCreateFromStateMem) 1039 1040 # define RTFuzzCtxInputGenerate RT_MANGLER(RTFuzzCtxInputGenerate) 1040 1041 # define RTFuzzCtxRelease RT_MANGLER(RTFuzzCtxRelease) … … 1043 1044 # define RTFuzzCtxStateExport RT_MANGLER(RTFuzzCtxStateExport) 1044 1045 # define RTFuzzCtxStateExportToFile RT_MANGLER(RTFuzzCtxStateExportToFile) 1046 # define RTFuzzCtxStateExportToMem RT_MANGLER(RTFuzzCtxStateExportToMem) 1045 1047 # define RTFuzzInputAddToCtxCorpus RT_MANGLER(RTFuzzInputAddToCtxCorpus) 1046 1048 # define RTFuzzInputMutateStreamData RT_MANGLER(RTFuzzInputMutateStreamData) -
trunk/src/VBox/Runtime/common/fuzz/fuzz-observer.cpp
r77482 r77509 60 60 #define RTFUZZOBS_EXEC_CTX_POLL_ID_STDIN 2 61 61 62 /** Length of the input queue for an observer thread. */ 63 # define RTFUZZOBS_THREAD_INPUT_QUEUE_MAX UINT32_C(5) 62 64 63 65 /********************************************************************************************************************************* … … 81 83 /** Pointer to te global observer state. */ 82 84 PRTFUZZOBSINT pFuzzObs; 83 /** Current fuzzer input. */ 84 RTFUZZINPUT hFuzzInput; 85 /** Flag whether to keep the input. */ 86 bool fKeepInput; 87 /** Flag whether a new input is waiting. */ 88 volatile bool fNewInput; 85 /** Number of inputs in the queue. */ 86 volatile uint32_t cInputs; 87 /** Where to insert the next input. */ 88 volatile uint32_t offQueueInputW; 89 /** Where to retrieve the next input from. */ 90 volatile uint32_t offQueueInputR; 91 /** The input queue for this thread. */ 92 RTFUZZINPUT ahQueueInput[RTFUZZOBS_THREAD_INPUT_QUEUE_MAX]; 89 93 } RTFUZZOBSTHRD; 90 94 /** Pointer to an observer thread state. */ … … 670 674 void *pvState = NULL; 671 675 size_t cbState = 0; 672 rc = RTFuzzCtxStateExport (pThis->hFuzzCtx, &pvState, &cbState);676 rc = RTFuzzCtxStateExportToMem(pThis->hFuzzCtx, &pvState, &cbState); 673 677 if (RT_SUCCESS(rc)) 674 678 { … … 841 845 842 846 /* Wait for work. */ 843 rc = RTThreadUserWait(hThrd, RT_INDEFINITE_WAIT); 844 AssertRC(rc); 847 if (!ASMAtomicReadU32(&pObsThrd->cInputs)) 848 { 849 rc = RTThreadUserWait(hThrd, RT_INDEFINITE_WAIT); 850 AssertRC(rc); 851 } 845 852 846 853 if (pObsThrd->fShutdown) 847 854 break; 848 855 849 if (!ASMAtomic XchgBool(&pObsThrd->fNewInput, false))856 if (!ASMAtomicReadU32(&pObsThrd->cInputs)) 850 857 continue; 851 858 852 AssertPtr(pObsThrd->hFuzzInput); 859 uint32_t offRead = ASMAtomicReadU32(&pObsThrd->offQueueInputR); 860 RTFUZZINPUT hFuzzInput = pObsThrd->ahQueueInput[offRead]; 861 862 ASMAtomicDecU32(&pObsThrd->cInputs); 863 offRead = (offRead + 1) % RT_ELEMENTS(pObsThrd->ahQueueInput); 864 ASMAtomicWriteU32(&pObsThrd->offQueueInputR, offRead); 865 if (!ASMAtomicBitTestAndSet(&pThis->bmEvt, pObsThrd->idObs)) 866 RTSemEventSignal(pThis->hEvtGlobal); 853 867 854 868 if (pThis->enmInputChan == RTFUZZOBSINPUTCHAN_FILE) … … 863 877 AssertRC(rc); 864 878 865 rc = RTFuzzInputWriteToFile( pObsThrd->hFuzzInput, &szInput[0]);879 rc = RTFuzzInputWriteToFile(hFuzzInput, &szInput[0]); 866 880 if (RT_SUCCESS(rc)) 867 881 { … … 875 889 else if (pThis->enmInputChan == RTFUZZOBSINPUTCHAN_STDIN) 876 890 { 877 rc = RTFuzzInputQueryBlobData( pObsThrd->hFuzzInput, (void **)&pExecCtx->pbInputCur, &pExecCtx->cbInputLeft);891 rc = RTFuzzInputQueryBlobData(hFuzzInput, (void **)&pExecCtx->pbInputCur, &pExecCtx->cbInputLeft); 878 892 if (RT_SUCCESS(rc)) 879 893 rc = rtFuzzObsExecCtxArgvPrepare(pThis, pExecCtx, NULL); … … 897 911 { 898 912 ASMAtomicIncU32(&pThis->Stats.cFuzzedInputsCrash); 899 rc = rtFuzzObsAddInputToResults(pThis, pObsThrd->hFuzzInput, pExecCtx);913 rc = rtFuzzObsAddInputToResults(pThis, hFuzzInput, pExecCtx); 900 914 } 901 915 } … … 903 917 { 904 918 ASMAtomicIncU32(&pThis->Stats.cFuzzedInputsHang); 905 rc = rtFuzzObsAddInputToResults(pThis, pObsThrd->hFuzzInput, pExecCtx);919 rc = rtFuzzObsAddInputToResults(pThis, hFuzzInput, pExecCtx); 906 920 } 907 921 else 908 922 AssertFailed(); 909 923 910 ASMAtomicXchgBool(&pObsThrd->fKeepInput, true); 924 RTFuzzInputAddToCtxCorpus(hFuzzInput); 925 RTFuzzInputRelease(hFuzzInput); 911 926 912 927 if (pThis->enmInputChan == RTFUZZOBSINPUTCHAN_FILE) 913 928 RTFileDelete(&szInput[0]); 914 929 } 915 916 ASMAtomicBitSet(&pThis->bmEvt, pObsThrd->idObs);917 RTSemEventSignal(pThis->hEvtGlobal);918 930 } 919 931 … … 924 936 925 937 /** 938 * Fills the input queue of the given observer thread until it is full. 939 * 940 * @returns IPRT status code. 941 * @param pThis Pointer to the observer instance data. 942 * @param pObsThrd The observer thread instance to fill. 943 */ 944 static int rtFuzzObsMasterInputQueueFill(PRTFUZZOBSINT pThis, PRTFUZZOBSTHRD pObsThrd) 945 { 946 int rc = VINF_SUCCESS; 947 uint32_t cInputsAdded = 0; 948 uint32_t cInputsAdd = RTFUZZOBS_THREAD_INPUT_QUEUE_MAX - ASMAtomicReadU32(&pObsThrd->cInputs); 949 uint32_t offW = ASMAtomicReadU32(&pObsThrd->offQueueInputW); 950 951 while ( cInputsAdded < cInputsAdd 952 && RT_SUCCESS(rc)) 953 { 954 RTFUZZINPUT hFuzzInput = NIL_RTFUZZINPUT; 955 rc = RTFuzzCtxInputGenerate(pThis->hFuzzCtx, &hFuzzInput); 956 if (RT_SUCCESS(rc)) 957 { 958 pObsThrd->ahQueueInput[offW] = hFuzzInput; 959 offW = (offW + 1) % RTFUZZOBS_THREAD_INPUT_QUEUE_MAX; 960 cInputsAdded++; 961 } 962 } 963 964 ASMAtomicWriteU32(&pObsThrd->offQueueInputW, offW); 965 ASMAtomicAddU32(&pObsThrd->cInputs, cInputsAdded); 966 967 return rc; 968 } 969 970 971 /** 926 972 * Fuzzing observer master worker loop. 927 973 * 928 974 * @returns IPRT status code. 929 * @param hThread 975 * @param hThread The thread handle. 930 976 * @param pvUser Opaque user data. 931 977 */ … … 950 996 PRTFUZZOBSTHRD pObsThrd = &pThis->paObsThreads[idxObs]; 951 997 952 /* Release the old input. */ 953 if (pObsThrd->hFuzzInput) 954 { 955 if (pObsThrd->fKeepInput) 956 { 957 int rc2 = RTFuzzInputAddToCtxCorpus(pObsThrd->hFuzzInput); 958 Assert(RT_SUCCESS(rc2) || rc2 == VERR_ALREADY_EXISTS); RT_NOREF(rc2); 959 pObsThrd->fKeepInput= false; 960 } 961 RTFuzzInputRelease(pObsThrd->hFuzzInput); 962 } 963 964 rc = RTFuzzCtxInputGenerate(pThis->hFuzzCtx, &pObsThrd->hFuzzInput); 998 rc = rtFuzzObsMasterInputQueueFill(pThis, pObsThrd); 965 999 if (RT_SUCCESS(rc)) 966 {967 ASMAtomicWriteBool(&pObsThrd->fNewInput, true);968 1000 RTThreadUserSignal(pObsThrd->hThread); 969 }970 1001 } 971 1002 … … 991 1022 static int rtFuzzObsWorkerThreadInit(PRTFUZZOBSINT pThis, uint32_t idObs, PRTFUZZOBSTHRD pObsThrd) 992 1023 { 993 pObsThrd->pFuzzObs = pThis; 994 pObsThrd->hFuzzInput = NULL; 995 pObsThrd->idObs = idObs; 996 pObsThrd->fShutdown = false; 1024 pObsThrd->pFuzzObs = pThis; 1025 pObsThrd->idObs = idObs; 1026 pObsThrd->fShutdown = false; 1027 pObsThrd->cInputs = 0; 1028 pObsThrd->offQueueInputW = 0; 1029 pObsThrd->offQueueInputR = 0; 997 1030 998 1031 ASMAtomicBitSet(&pThis->bmEvt, idObs); … … 1318 1351 RTThreadUserSignal(pThrd->hThread); 1319 1352 RTThreadWait(pThrd->hThread, RT_INDEFINITE_WAIT, NULL); 1320 if (pThrd->hFuzzInput)1321 RTFuzzInputRelease(pThrd->hFuzzInput);1322 1353 } 1323 1354 -
trunk/src/VBox/Runtime/common/fuzz/fuzz.cpp
r77489 r77509 87 87 * @param pThis The fuzzer context instance. 88 88 * @param pMutation The mutation to work on. 89 * @param pvMutation Mutation dependent data. 89 90 * @param pbBuf The buffer to work on. 90 91 * @param cbBuf Size of the remaining buffer. 91 92 */ 92 typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXEC(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 93 typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXEC(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 93 94 uint8_t *pbBuf, size_t cbBuf); 94 95 /** Pointer to a mutator execution callback. */ 95 96 typedef FNRTFUZZCTXMUTATOREXEC *PFNRTFUZZCTXMUTATOREXEC; 97 98 99 /** 100 * Mutator export callback. 101 * 102 * @returns IPRT status code. 103 * @param pThis The fuzzer context instance. 104 * @param pMutation The mutation to work on. 105 * @param pvMutation Mutation dependent data. 106 * @param pfnExport The export callback. 107 * @param pvUser Opaque user data to pass to the export callback. 108 */ 109 typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXPORT(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 110 PFNRTFUZZCTXEXPORT pfnExport, void *pvUser); 111 /** Pointer to a mutator export callback. */ 112 typedef FNRTFUZZCTXMUTATOREXPORT *PFNRTFUZZCTXMUTATOREXPORT; 113 114 115 /** 116 * Mutator import callback. 117 * 118 * @returns IPRT status code. 119 * @param pThis The fuzzer context instance. 120 * @param pMutation The mutation to work on. 121 * @param pvMutation Mutation dependent data. 122 * @param pfnExport The import callback. 123 * @param pvUser Opaque user data to pass to the import callback. 124 */ 125 typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATORIMPORT(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, void *pvMutation, 126 PFNRTFUZZCTXIMPORT pfnImport, void *pvUser); 127 /** Pointer to a mutator import callback. */ 128 typedef FNRTFUZZCTXMUTATORIMPORT *PFNRTFUZZCTXMUTATORIMPORT; 96 129 97 130 … … 105 138 /** Mutator description. */ 106 139 const char *pszDesc; 140 /** Mutator index. */ 141 uint32_t uMutator; 107 142 /** Additional flags for the mutator, controlling the behavior. */ 108 143 uint64_t fFlags; … … 111 146 /** The execution callback. */ 112 147 PFNRTFUZZCTXMUTATOREXEC pfnExec; 148 /** The export callback. */ 149 PFNRTFUZZCTXMUTATOREXPORT pfnExport; 150 /** The import callback. */ 151 PFNRTFUZZCTXMUTATORIMPORT pfnImport; 113 152 } RTFUZZMUTATOR; 114 153 /** Pointer to a fuzzing mutator descriptor. */ … … 116 155 /** Pointer to a const fuzzing mutator descriptor. */ 117 156 typedef const RTFUZZMUTATOR *PCRTFUZZMUTATOR; 157 158 /** The special corpus mutator. */ 159 #define RTFUZZMUTATOR_ID_CORPUS UINT32_C(0xffffffff) 118 160 119 161 /** Mutator always works from the end of the buffer (no starting offset generation). */ … … 146 188 /** Size of the generated input data in bytes after the mutation was applied. */ 147 189 size_t cbInput; 148 /** Mutation dependent data. */ 149 union 150 { 151 /** Array of bytes making up the corups, variable in size. */ 152 uint8_t abCorpus[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; 153 /** Bit flip mutation, which bit to flip. */ 154 uint32_t idxBitFlip; 155 /** Byte replace, the byte to replace with. */ 156 uint8_t bByteReplace; 157 /** Array of bytes to insert/append, variable in size. */ 158 uint8_t abAdd[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION]; 159 } u; 190 /** Size of the mutation dependent data. */ 191 size_t cbMutation; 192 /** Mutation dependent data, variable in size. */ 193 uint8_t abMutation[1]; 160 194 } RTFUZZMUTATION; 161 195 … … 242 276 /** Magic value for identification. */ 243 277 uint32_t u32Magic; 278 /** Context type. */ 279 uint32_t uCtxType; 244 280 /** Size of the PRNG state following in bytes. */ 245 281 uint32_t cbPrng; 246 /** Number of input descriptors following. */ 247 uint32_t cInputs; 282 /** Number of mutator descriptors following. */ 283 uint32_t cMutators; 284 /** Number of mutation descriptors following. */ 285 uint32_t cMutations; 248 286 /** Behavioral flags. */ 249 287 uint32_t fFlagsBehavioral; … … 253 291 /** Pointer to a fuzzing context state. */ 254 292 typedef RTFUZZCTXSTATE *PRTFUZZCTXSTATE; 293 294 /** BLOB context type. */ 295 #define RTFUZZCTX_STATE_TYPE_BLOB UINT32_C(0) 296 /** Stream context type. */ 297 #define RTFUZZCTX_STATE_TYPE_STREAM UINT32_C(1) 298 299 300 /** 301 * The fuzzer mutation state to be exported - all members are stored in little endian form. 302 */ 303 typedef struct RTFUZZMUTATIONSTATE 304 { 305 /** The mutation identifier. */ 306 uint64_t u64Id; 307 /** The mutation identifier of the parent, 0 for no parent. */ 308 uint64_t u64IdParent; 309 /** The byte offset where the mutation starts. */ 310 uint64_t u64OffMutation; 311 /** Size of input data after mutation was applied. */ 312 uint64_t cbInput; 313 /** Size of mutation dependent data following. */ 314 uint64_t cbMutation; 315 /** The mutator ID. */ 316 uint32_t u32IdMutator; 317 /** The mutation level. */ 318 uint32_t iLvl; 319 /** Magic value for identification. */ 320 uint32_t u32Magic; 321 } RTFUZZMUTATIONSTATE; 255 322 256 323 … … 276 343 277 344 345 /** 346 * Fuzzing context export AVL arguments. 347 */ 348 typedef struct RTFUZZEXPORTARGS 349 { 350 /** Pointer to the export callback. */ 351 PFNRTFUZZCTXEXPORT pfnExport; 352 /** Opaque user data to pass to the callback. */ 353 void *pvUser; 354 } RTFUZZEXPORTARGS; 355 /** Pointer to the export arguments. */ 356 typedef RTFUZZEXPORTARGS *PRTFUZZEXPORTARGS; 357 /** Pointer to the constant export arguments. */ 358 typedef const RTFUZZEXPORTARGS *PCRTFUZZEXPORTARGS; 359 278 360 279 361 /********************************************************************************************************************************* … … 291 373 PPRTFUZZMUTATION ppMutation); 292 374 293 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 375 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 294 376 uint8_t *pbBuf, size_t cbBuf); 295 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 377 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 296 378 uint8_t *pbBuf, size_t cbBuf); 297 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 379 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 298 380 uint8_t *pbBuf, size_t cbBuf); 299 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 381 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 300 382 uint8_t *pbBuf, size_t cbBuf); 301 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 383 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 302 384 uint8_t *pbBuf, size_t cbBuf); 303 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 385 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 304 386 uint8_t *pbBuf, size_t cbBuf); 305 387 388 static DECLCALLBACK(int) rtFuzzCtxMutatorExportDefault(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 389 PFNRTFUZZCTXEXPORT pfnExport, void *pvUser); 390 static DECLCALLBACK(int) rtFuzzCtxMutatorImportDefault(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, void *pvMutation, 391 PFNRTFUZZCTXIMPORT pfnImport, void *pvUser); 306 392 307 393 /********************************************************************************************************************************* … … 317 403 /** pszDesc */ 318 404 "Special mutator, which is assigned to the initial corpus", 405 /** uMutator. */ 406 RTFUZZMUTATOR_ID_CORPUS, 319 407 /** fFlags */ 320 408 RTFUZZMUTATOR_F_DEFAULT, … … 322 410 NULL, 323 411 /** pfnExec */ 324 rtFuzzCtxMutatorCorpusExec 412 rtFuzzCtxMutatorCorpusExec, 413 /** pfnExport */ 414 rtFuzzCtxMutatorExportDefault, 415 /** pfnImport */ 416 rtFuzzCtxMutatorImportDefault 325 417 }; 326 418 … … 330 422 static RTFUZZMUTATOR const g_aMutators[] = 331 423 { 332 /* pszId pszDesc fFlags pfnPrep pfnExec*/333 { "BitFlip", "Flips a single bit in the input", RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorBitFlipPrep, rtFuzzCtxMutatorBitFlipExec},334 { "ByteReplace", "Replaces a single byte in the input", RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteReplacePrep, rtFuzzCtxMutatorByteReplaceExec},335 { "ByteSeqIns", "Inserts a byte sequence in the input", RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec},336 { "ByteSeqApp", "Appends a byte sequence to the input", RTFUZZMUTATOR_F_END_OF_BUF, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec},337 { "ByteDelete", "Deletes a single byte sequence from the input", RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteDeletePrep, rtFuzzCtxMutatorByteDeleteExec},338 { "ByteSeqDel", "Deletes a byte sequence from the input", RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceDeletePrep, rtFuzzCtxMutatorByteSequenceDeleteExec}424 /* pszId pszDesc uMutator fFlags pfnPrep pfnExec pfnExport pfnImport */ 425 { "BitFlip", "Flips a single bit in the input", 0, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorBitFlipPrep, rtFuzzCtxMutatorBitFlipExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 426 { "ByteReplace", "Replaces a single byte in the input", 1, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteReplacePrep, rtFuzzCtxMutatorByteReplaceExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 427 { "ByteSeqIns", "Inserts a byte sequence in the input", 2, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 428 { "ByteSeqApp", "Appends a byte sequence to the input", 3, RTFUZZMUTATOR_F_END_OF_BUF, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 429 { "ByteDelete", "Deletes a single byte sequence from the input", 4, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteDeletePrep, rtFuzzCtxMutatorByteDeleteExec, NULL, NULL }, 430 { "ByteSeqDel", "Deletes a byte sequence from the input", 5, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceDeletePrep, rtFuzzCtxMutatorByteSequenceDeleteExec, NULL, NULL } 339 431 }; 340 432 … … 416 508 int rc = VINF_SUCCESS; 417 509 418 pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations) - 1;510 pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations); 419 511 rc = RTSemRWRequestWrite(pThis->hSemRwMutations, RT_INDEFINITE_WAIT); 420 512 AssertRC(rc); RT_NOREF(rc); … … 465 557 * @param pMutationParent The parent mutation, can be NULL. 466 558 * @param cbAdditional Additional number of bytes to allocate after the core structure. 467 */ 468 static PRTFUZZMUTATION rtFuzzMutationCreate(PRTFUZZCTXINT pThis, uint64_t offMutation, PRTFUZZMUTATION pMutationParent, size_t cbAdditional) 559 * @param ppvMutation Where to store the pointer to the mutation dependent data on success. 560 */ 561 static PRTFUZZMUTATION rtFuzzMutationCreate(PRTFUZZCTXINT pThis, uint64_t offMutation, PRTFUZZMUTATION pMutationParent, 562 size_t cbAdditional, void **ppvMutation) 469 563 { 470 564 PRTFUZZMUTATION pMutation = (PRTFUZZMUTATION)rtFuzzCtxMemoryAlloc(pThis, sizeof(RTFUZZMUTATION) + cbAdditional); … … 477 571 pMutation->offMutation = offMutation; 478 572 pMutation->pMutationParent = pMutationParent; 573 pMutation->cbMutation = cbAdditional; 479 574 480 575 if (pMutationParent) 481 576 pMutation->iLvl = pMutationParent->iLvl + 1; 577 if (ppvMutation) 578 *ppvMutation = &pMutation->abMutation[0]; 482 579 } 483 580 … … 510 607 511 608 512 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 609 /** 610 * Default mutator export callback (just writing the raw data). 611 */ 612 static DECLCALLBACK(int) rtFuzzCtxMutatorExportDefault(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 613 PFNRTFUZZCTXEXPORT pfnExport, void *pvUser) 614 { 615 return pfnExport(pThis, pvMutation, pMutation->cbMutation, pvUser); 616 } 617 618 619 /** 620 * Default mutator import callback (just reading the raw data). 621 */ 622 static DECLCALLBACK(int) rtFuzzCtxMutatorImportDefault(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, void *pvMutation, 623 PFNRTFUZZCTXIMPORT pfnImport, void *pvUser) 624 { 625 return pfnImport(pThis, pvMutation, pMutation->cbMutation, NULL, pvUser); 626 } 627 628 629 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 513 630 uint8_t *pbBuf, size_t cbBuf) 514 631 { 515 RT_NOREF(pThis, cbBuf );516 memcpy(pbBuf, &pMutation->u.abCorpus[0], pMutation->cbInput);632 RT_NOREF(pThis, cbBuf, pvMutation); 633 memcpy(pbBuf, pvMutation, pMutation->cbInput); 517 634 return VINF_SUCCESS; 518 635 } … … 526 643 { 527 644 int rc = VINF_SUCCESS; 528 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 645 uint8_t *pidxBitFlip = 0; 646 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, sizeof(*pidxBitFlip), (void **)&pidxBitFlip); 529 647 if (RT_LIKELY(pMutation)) 530 648 { 531 pMutation->cbInput 532 pMutation->u.idxBitFlip = RTRandAdvS32Ex(pThis->hRand, 0, sizeof(uint8_t) * 8 - 1);649 pMutation->cbInput = pMutationParent->cbInput; /* Bit flips don't change the input size. */ 650 *pidxBitFlip = (uint8_t)RTRandAdvU32Ex(pThis->hRand, 0, sizeof(uint8_t) * 8 - 1); 533 651 *ppMutation = pMutation; 534 652 } … … 540 658 541 659 542 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 660 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 543 661 uint8_t *pbBuf, size_t cbBuf) 544 662 { 545 RT_NOREF(pThis, cbBuf); 546 ASMBitToggle(pbBuf, pMutation->u.idxBitFlip); 663 RT_NOREF(pThis, cbBuf, pMutation); 664 uint8_t idxBitFlip = *(uint8_t *)pvMutation; 665 ASMBitToggle(pbBuf, idxBitFlip); 547 666 return VINF_SUCCESS; 548 667 } … … 556 675 { 557 676 int rc = VINF_SUCCESS; 558 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 677 uint8_t *pbReplace = 0; 678 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, sizeof(*pbReplace), (void **)&pbReplace); 559 679 if (RT_LIKELY(pMutation)) 560 680 { 561 681 pMutation->cbInput = pMutationParent->cbInput; /* Byte replacements don't change the input size. */ 562 RTRandAdvBytes(pThis->hRand, &pMutation->u.bByteReplace, 1); /** @todo Filter out same values. */682 RTRandAdvBytes(pThis->hRand, pbReplace, 1); /** @todo Filter out same values. */ 563 683 *ppMutation = pMutation; 564 684 } … … 570 690 571 691 572 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 692 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 573 693 uint8_t *pbBuf, size_t cbBuf) 574 694 { 575 RT_NOREF(pThis, cbBuf); 576 *pbBuf = pMutation->u.bByteReplace; 695 RT_NOREF(pThis, cbBuf, pMutation); 696 uint8_t bReplace = *(uint8_t *)pvMutation; 697 *pbBuf = bReplace; 577 698 return VINF_SUCCESS; 578 699 } … … 590 711 size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, pMutationParent->cbInput + 1, pThis->cbInputMax); 591 712 size_t cbInsert = cbInputMutated - pMutationParent->cbInput; 592 593 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, cbInsert); 713 uint8_t *pbAdd = NULL; 714 715 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, cbInsert, (void **)&pbAdd); 594 716 if (RT_LIKELY(pMutation)) 595 717 { 596 718 pMutation->cbInput = cbInputMutated; 597 RTRandAdvBytes(pThis->hRand, &pMutation->u.abAdd[0], cbInsert);719 RTRandAdvBytes(pThis->hRand, pbAdd, cbInsert); 598 720 *ppMutation = pMutation; 599 721 } … … 606 728 607 729 608 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 730 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 609 731 uint8_t *pbBuf, size_t cbBuf) 610 732 { … … 616 738 memmove(pbBuf + cbInsert, pbBuf, cbBuf); 617 739 618 memcpy(pbBuf, &pMutation->u.abAdd[0], cbInsert);740 memcpy(pbBuf, pvMutation, cbInsert); 619 741 return VINF_SUCCESS; 620 742 } … … 630 752 if (pMutationParent->cbInput - offStart >= 1) 631 753 { 632 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/ );754 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/, NULL); 633 755 if (RT_LIKELY(pMutation)) 634 756 { … … 644 766 645 767 646 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 768 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 647 769 uint8_t *pbBuf, size_t cbBuf) 648 770 { 649 RT_NOREF(pThis, pMutation );771 RT_NOREF(pThis, pMutation, pvMutation); 650 772 651 773 /* Just move the residual data to the front. */ … … 667 789 size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, offStart, pMutationParent->cbInput - 1); 668 790 669 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/ );791 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/, NULL); 670 792 if (RT_LIKELY(pMutation)) 671 793 { … … 681 803 682 804 683 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 805 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 684 806 uint8_t *pbBuf, size_t cbBuf) 685 807 { 686 RT_NOREF(pThis );808 RT_NOREF(pThis, pvMutation); 687 809 Assert(pMutation->pMutationParent->cbInput > pMutation->cbInput); 688 810 size_t cbDel = pMutation->pMutationParent->cbInput - pMutation->cbInput; … … 789 911 { 790 912 PCRTFUZZMUTATION pMutation = pThis->apMutations[i]; 791 pMutation->pMutator->pfnExec(pThis->pFuzzer, pMutation, pbBuf + pMutation->offMutation, 913 pMutation->pMutator->pfnExec(pThis->pFuzzer, pMutation, (void *)&pMutation->abMutation[0], 914 pbBuf + pMutation->offMutation, 792 915 cbInputNow - pMutation->offMutation); 793 916 … … 812 935 813 936 814 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState)937 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, PFNRTFUZZCTXIMPORT pfnImport, void *pvUser) 815 938 { 816 939 AssertPtrReturn(phFuzzCtx, VERR_INVALID_POINTER); 817 AssertPtrReturn(pvState, VERR_INVALID_POINTER); 818 AssertReturn(cbState > 0, VERR_INVALID_PARAMETER); 940 AssertPtrReturn(pfnImport, VERR_INVALID_POINTER); 819 941 820 942 #if 0 … … 895 1017 return rc; 896 1018 #else 1019 RT_NOREF(pvUser); 897 1020 return VERR_NOT_IMPLEMENTED; 898 1021 #endif 1022 } 1023 1024 1025 RTDECL(int) RTFuzzCtxCreateFromStateMem(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState) 1026 { 1027 AssertPtrReturn(phFuzzCtx, VERR_INVALID_POINTER); 1028 AssertPtrReturn(pvState, VERR_INVALID_POINTER); 1029 AssertPtrReturn(cbState, VERR_INVALID_POINTER); 1030 1031 return VERR_NOT_IMPLEMENTED; 899 1032 } 900 1033 … … 910 1043 if (RT_SUCCESS(rc)) 911 1044 { 912 rc = RTFuzzCtxCreateFromState (phFuzzCtx, pv, cb);1045 rc = RTFuzzCtxCreateFromStateMem(phFuzzCtx, pv, cb); 913 1046 RTFileReadAllFree(pv, cb); 914 1047 } … … 945 1078 946 1079 947 RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState) 1080 /** 1081 * Fuzzing context export callback for a single mutation. 1082 */ 1083 static DECLCALLBACK(int) rtFuzzCtxStateExportMutations(PAVLU64NODECORE pCore, void *pvParam) 1084 { 1085 PRTFUZZMUTATION pMutation = (PRTFUZZMUTATION)pCore; 1086 PCRTFUZZMUTATOR pMutator = pMutation->pMutator; 1087 PCRTFUZZEXPORTARGS pArgs = (PCRTFUZZEXPORTARGS)pvParam; 1088 RTFUZZMUTATIONSTATE MutationState; 1089 1090 MutationState.u64Id = RT_H2LE_U64(pMutation->Core.Key); 1091 if (pMutation->pMutationParent) 1092 MutationState.u64IdParent = RT_H2LE_U64(pMutation->pMutationParent->Core.Key); 1093 else 1094 MutationState.u64IdParent = RT_H2LE_U64(0); 1095 MutationState.u64OffMutation = RT_H2LE_U64(pMutation->offMutation); 1096 MutationState.cbInput = RT_H2LE_U64((uint64_t)pMutation->cbInput); 1097 MutationState.cbMutation = RT_H2LE_U64((uint64_t)pMutation->cbMutation); 1098 MutationState.u32IdMutator = RT_H2LE_U32(pMutator->uMutator); 1099 MutationState.iLvl = RT_H2LE_U32(pMutation->iLvl); 1100 MutationState.u32Magic = RT_H2LE_U32(pMutation->u32Magic); 1101 1102 int rc = pArgs->pfnExport(pMutation->pFuzzer, &MutationState, sizeof(MutationState), pArgs->pvUser); 1103 if ( RT_SUCCESS(rc) 1104 && pMutator->pfnExport) 1105 rc = pMutator->pfnExport(pMutation->pFuzzer, pMutation, &pMutation->abMutation[0], pArgs->pfnExport, pArgs->pvUser); 1106 return rc; 1107 } 1108 1109 1110 RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, PFNRTFUZZCTXEXPORT pfnExport, void *pvUser) 1111 { 1112 PRTFUZZCTXINT pThis = hFuzzCtx; 1113 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1114 AssertPtrReturn(pfnExport, VERR_INVALID_POINTER); 1115 1116 char aszPrngExport[_4K]; /* Should be plenty of room here. */ 1117 size_t cbPrng = sizeof(aszPrngExport); 1118 int rc = RTRandAdvSaveState(pThis->hRand, &aszPrngExport[0], &cbPrng); 1119 if (RT_SUCCESS(rc)) 1120 { 1121 RTFUZZCTXSTATE StateExport; 1122 1123 StateExport.u32Magic = RT_H2LE_U32(RTFUZZCTX_MAGIC); 1124 switch (pThis->enmType) 1125 { 1126 case RTFUZZCTXTYPE_BLOB: 1127 StateExport.uCtxType = RT_H2LE_U32(RTFUZZCTX_STATE_TYPE_BLOB); 1128 break; 1129 case RTFUZZCTXTYPE_STREAM: 1130 StateExport.uCtxType = RT_H2LE_U32(RTFUZZCTX_STATE_TYPE_STREAM); 1131 break; 1132 default: 1133 AssertFailed(); 1134 break; 1135 } 1136 StateExport.cbPrng = RT_H2LE_U32((uint32_t)cbPrng); 1137 StateExport.cMutations = RT_H2LE_U32(pThis->cMutations); 1138 StateExport.cMutators = RT_H2LE_U32(pThis->cMutators); 1139 StateExport.fFlagsBehavioral = RT_H2LE_U32(pThis->fFlagsBehavioral); 1140 StateExport.cbInputMax = RT_H2LE_U64(pThis->cbInputMax); 1141 1142 /* Write the context state and PRNG state first. */ 1143 rc = pfnExport(pThis, &StateExport, sizeof(StateExport), pvUser); 1144 if (RT_SUCCESS(rc)) 1145 rc = pfnExport(pThis, &aszPrngExport[0], cbPrng, pvUser); 1146 if (RT_SUCCESS(rc)) 1147 { 1148 /* Write the mutator descriptors next. */ 1149 for (uint32_t i = 0; i < pThis->cMutators && RT_SUCCESS(rc); i++) 1150 { 1151 PRTFUZZMUTATOR pMutator = &pThis->paMutators[i]; 1152 uint32_t cchId = (uint32_t)strlen(pMutator->pszId) + 1; 1153 uint32_t cchIdW = RT_H2LE_U32(cchId); 1154 1155 rc = pfnExport(pThis, &cchIdW, sizeof(cchIdW), pvUser); 1156 if (RT_SUCCESS(rc)) 1157 rc = pfnExport(pThis, &pMutator->pszId[0], cchId, pvUser); 1158 } 1159 } 1160 1161 /* Write the mutations last. */ 1162 if (RT_SUCCESS(rc)) 1163 { 1164 RTFUZZEXPORTARGS Args; 1165 1166 Args.pfnExport = pfnExport; 1167 Args.pvUser = pvUser; 1168 rc = RTAvlU64DoWithAll(&pThis->TreeMutations, true /*fFromLeft*/, rtFuzzCtxStateExportMutations, &Args); 1169 } 1170 } 1171 1172 return rc; 1173 } 1174 1175 1176 RTDECL(int) RTFuzzCtxStateExportToMem(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState) 948 1177 { 949 1178 PRTFUZZCTXINT pThis = hFuzzCtx; … … 952 1181 AssertPtrReturn(pcbState, VERR_INVALID_POINTER); 953 1182 954 #if 0955 char aszPrngExport[_4K]; /* Should be plenty of room here. */956 size_t cbPrng = sizeof(aszPrngExport);957 int rc = RTRandAdvSaveState(pThis->hRand, &aszPrngExport[0], &cbPrng);958 if (RT_SUCCESS(rc))959 {960 RTFUZZCTXSTATE StateExport;961 962 StateExport.u32Magic = RT_H2LE_U32(RTFUZZCTX_MAGIC);963 StateExport.cbPrng = RT_H2LE_U32((uint32_t)cbPrng);964 StateExport.cInputs = RT_H2LE_U32(pThis->cInputs);965 StateExport.fFlagsBehavioral = RT_H2LE_U32(pThis->fFlagsBehavioral);966 StateExport.cbInputMax = RT_H2LE_U64(pThis->cbInputMax);967 968 /* Estimate the size of the required state. */969 size_t cbState = sizeof(StateExport)970 + cbPrng971 + pThis->cInputs * ((pThis->cbInputMax < _1M ? pThis->cbInputMax : _64K) + sizeof(uint32_t)); /* For the size indicator before each input. */972 uint8_t *pbState = (uint8_t *)RTMemAllocZ(cbState);973 if (RT_LIKELY(pbState))974 {975 size_t offState = 0;976 memcpy(pbState, &StateExport, sizeof(StateExport));977 offState += sizeof(StateExport);978 memcpy(&pbState[offState], &aszPrngExport[0], cbPrng);979 offState += cbPrng;980 981 /* Export each input. */982 PRTFUZZINPUTINT pIt;983 RTListForEach(&pThis->LstInputs, pIt, RTFUZZINPUTINT, NdInputs)984 {985 /* Ensure buffer size. */986 if (offState + pIt->cbInput + sizeof(uint32_t) > cbState)987 {988 uint8_t *pbStateNew = (uint8_t *)RTMemRealloc(pbState, cbState + pIt->cbInput + sizeof(uint32_t));989 if (RT_LIKELY(pbStateNew))990 {991 pbState = pbStateNew;992 cbState += pIt->cbInput + sizeof(uint32_t);993 }994 else995 {996 rc = VERR_NO_MEMORY;997 break;998 }999 }1000 1001 *(uint32_t *)&pbState[offState] = RT_H2LE_U32((uint32_t)pIt->cbInput);1002 offState += sizeof(uint32_t);1003 memcpy(&pbState[offState], &pIt->abInput[0], pIt->cbInput);1004 offState += pIt->cbInput;1005 }1006 1007 if (RT_SUCCESS(rc))1008 {1009 *ppvState = pbState;1010 *pcbState = offState;1011 }1012 else1013 RTMemFree(pbState);1014 }1015 else1016 rc = VERR_NO_MEMORY;1017 }1018 1019 return rc;1020 #else1021 1183 return VERR_NOT_IMPLEMENTED; 1022 #endif 1184 } 1185 1186 1187 /** 1188 * Export to file callback. 1189 */ 1190 DECLCALLBACK(int) rtFuzzCtxStateExportFile(RTFUZZCTX hFuzzCtx, const void *pvBuf, size_t cbWrite, void *pvUser) 1191 { 1192 RT_NOREF(hFuzzCtx); 1193 1194 RTFILE hFile = (RTFILE)pvUser; 1195 return RTFileWrite(hFile, pvBuf, cbWrite, NULL); 1023 1196 } 1024 1197 … … 1030 1203 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 1031 1204 1032 void *pvState = NULL; 1033 size_t cbState = 0; 1034 int rc = RTFuzzCtxStateExport(hFuzzCtx, &pvState, &cbState); 1205 RTFILE hFile; 1206 int rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1035 1207 if (RT_SUCCESS(rc)) 1036 1208 { 1037 RTFILE hFile; 1038 1039 rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1040 if (RT_SUCCESS(rc)) 1041 { 1042 rc = RTFileWrite(hFile, pvState, cbState, NULL); 1043 RTFileClose(hFile); 1044 if (RT_FAILURE(rc)) 1045 RTFileDelete(pszFilename); 1046 } 1047 1048 RTMemFree(pvState); 1209 rc = RTFuzzCtxStateExport(hFuzzCtx, rtFuzzCtxStateExportFile, hFile); 1210 RTFileClose(hFile); 1211 if (RT_FAILURE(rc)) 1212 RTFileDelete(pszFilename); 1049 1213 } 1050 1214 … … 1061 1225 1062 1226 int rc = VINF_SUCCESS; 1063 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbInput); 1227 void *pvCorpus = NULL; 1228 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbInput, &pvCorpus); 1064 1229 if (RT_LIKELY(pMutation)) 1065 1230 { 1066 1231 pMutation->pMutator = &g_MutatorCorpus; 1067 1232 pMutation->cbInput = cbInput; 1068 memcpy( &pMutation->u.abCorpus[0], pvInput, cbInput);1233 memcpy(pvCorpus, pvInput, cbInput); 1069 1234 rc = rtFuzzCtxMutationAdd(pThis, pMutation); 1070 1235 if (RT_FAILURE(rc)) … … 1104 1269 1105 1270 uint64_t cbFile = 0; 1271 void *pvCorpus = NULL; 1106 1272 int rc = RTVfsFileGetSize(hVfsFile, &cbFile); 1107 1273 if (RT_SUCCESS(rc)) 1108 1274 { 1109 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile );1275 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile, &pvCorpus); 1110 1276 if (RT_LIKELY(pMutation)) 1111 1277 { 1112 1278 pMutation->pMutator = &g_MutatorCorpus; 1113 1279 pMutation->cbInput = cbFile; 1114 rc = RTVfsFileRead(hVfsFile, &pMutation->u.abCorpus[0], cbFile, NULL);1280 rc = RTVfsFileRead(hVfsFile, pvCorpus, cbFile, NULL); 1115 1281 if (RT_SUCCESS(rc)) 1116 1282 rc = rtFuzzCtxMutationAdd(pThis, pMutation); -
trunk/src/VBox/Runtime/common/fuzz/fuzzclientcmd.cpp
r77482 r77509 133 133 if (RT_SUCCESS(rc)) 134 134 { 135 rc = RTFuzzCtxCreateFromState (&pThis->hFuzzCtx, pvFuzzCtxState, cbFuzzCtxState);135 rc = RTFuzzCtxCreateFromStateMem(&pThis->hFuzzCtx, pvFuzzCtxState, cbFuzzCtxState); 136 136 if (RT_SUCCESS(rc)) 137 137 rc = rtFuzzCmdClientMainloop(pThis); -
trunk/src/VBox/Runtime/common/fuzz/fuzzmastercmd.cpp
r77482 r77509 886 886 void *pvState = NULL; 887 887 size_t cbState = 0; 888 rc = RTFuzzCtxStateExport (hFuzzCtx, &pvState, &cbState);888 rc = RTFuzzCtxStateExportToMem(hFuzzCtx, &pvState, &cbState); 889 889 if (RT_SUCCESS(rc)) 890 890 {
Note:
See TracChangeset
for help on using the changeset viewer.