- Timestamp:
- Feb 28, 2019 7:30:28 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129112
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fuzz/fuzz.cpp
r77511 r77512 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 … … 390 482 } 391 483 392 393 484 #if 0 /* unused */ 394 485 /** … … 406 497 #endif 407 498 408 409 499 /** 410 500 * Adds the given mutation to the corpus of the given fuzzer context. … … 418 508 int rc = VINF_SUCCESS; 419 509 420 pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations) - 1;510 pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations); 421 511 rc = RTSemRWRequestWrite(pThis->hSemRwMutations, RT_INDEFINITE_WAIT); 422 512 AssertRC(rc); RT_NOREF(rc); … … 467 557 * @param pMutationParent The parent mutation, can be NULL. 468 558 * @param cbAdditional Additional number of bytes to allocate after the core structure. 469 */ 470 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) 471 563 { 472 564 PRTFUZZMUTATION pMutation = (PRTFUZZMUTATION)rtFuzzCtxMemoryAlloc(pThis, sizeof(RTFUZZMUTATION) + cbAdditional); … … 479 571 pMutation->offMutation = offMutation; 480 572 pMutation->pMutationParent = pMutationParent; 573 pMutation->cbMutation = cbAdditional; 481 574 482 575 if (pMutationParent) 483 576 pMutation->iLvl = pMutationParent->iLvl + 1; 577 if (ppvMutation) 578 *ppvMutation = &pMutation->abMutation[0]; 484 579 } 485 580 … … 512 607 513 608 514 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, 515 630 uint8_t *pbBuf, size_t cbBuf) 516 631 { 517 RT_NOREF(pThis, cbBuf );518 memcpy(pbBuf, &pMutation->u.abCorpus[0], pMutation->cbInput);632 RT_NOREF(pThis, cbBuf, pvMutation); 633 memcpy(pbBuf, pvMutation, pMutation->cbInput); 519 634 return VINF_SUCCESS; 520 635 } … … 528 643 { 529 644 int rc = VINF_SUCCESS; 530 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 645 uint8_t *pidxBitFlip = 0; 646 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, sizeof(*pidxBitFlip), (void **)&pidxBitFlip); 531 647 if (RT_LIKELY(pMutation)) 532 648 { 533 pMutation->cbInput 534 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); 535 651 *ppMutation = pMutation; 536 652 } … … 542 658 543 659 544 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 660 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 545 661 uint8_t *pbBuf, size_t cbBuf) 546 662 { 547 RT_NOREF(pThis, cbBuf); 548 ASMBitToggle(pbBuf, pMutation->u.idxBitFlip); 663 RT_NOREF(pThis, cbBuf, pMutation); 664 uint8_t idxBitFlip = *(uint8_t *)pvMutation; 665 ASMBitToggle(pbBuf, idxBitFlip); 549 666 return VINF_SUCCESS; 550 667 } … … 558 675 { 559 676 int rc = VINF_SUCCESS; 560 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 677 uint8_t *pbReplace = 0; 678 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, sizeof(*pbReplace), (void **)&pbReplace); 561 679 if (RT_LIKELY(pMutation)) 562 680 { 563 681 pMutation->cbInput = pMutationParent->cbInput; /* Byte replacements don't change the input size. */ 564 RTRandAdvBytes(pThis->hRand, &pMutation->u.bByteReplace, 1); /** @todo Filter out same values. */682 RTRandAdvBytes(pThis->hRand, pbReplace, 1); /** @todo Filter out same values. */ 565 683 *ppMutation = pMutation; 566 684 } … … 572 690 573 691 574 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 692 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 575 693 uint8_t *pbBuf, size_t cbBuf) 576 694 { 577 RT_NOREF(pThis, cbBuf); 578 *pbBuf = pMutation->u.bByteReplace; 695 RT_NOREF(pThis, cbBuf, pMutation); 696 uint8_t bReplace = *(uint8_t *)pvMutation; 697 *pbBuf = bReplace; 579 698 return VINF_SUCCESS; 580 699 } … … 592 711 size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, pMutationParent->cbInput + 1, pThis->cbInputMax); 593 712 size_t cbInsert = cbInputMutated - pMutationParent->cbInput; 594 595 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, cbInsert); 713 uint8_t *pbAdd = NULL; 714 715 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, cbInsert, (void **)&pbAdd); 596 716 if (RT_LIKELY(pMutation)) 597 717 { 598 718 pMutation->cbInput = cbInputMutated; 599 RTRandAdvBytes(pThis->hRand, &pMutation->u.abAdd[0], cbInsert);719 RTRandAdvBytes(pThis->hRand, pbAdd, cbInsert); 600 720 *ppMutation = pMutation; 601 721 } … … 608 728 609 729 610 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 730 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 611 731 uint8_t *pbBuf, size_t cbBuf) 612 732 { … … 618 738 memmove(pbBuf + cbInsert, pbBuf, cbBuf); 619 739 620 memcpy(pbBuf, &pMutation->u.abAdd[0], cbInsert);740 memcpy(pbBuf, pvMutation, cbInsert); 621 741 return VINF_SUCCESS; 622 742 } … … 632 752 if (pMutationParent->cbInput - offStart >= 1) 633 753 { 634 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/ );754 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/, NULL); 635 755 if (RT_LIKELY(pMutation)) 636 756 { … … 646 766 647 767 648 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 768 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 649 769 uint8_t *pbBuf, size_t cbBuf) 650 770 { 651 RT_NOREF(pThis, pMutation );771 RT_NOREF(pThis, pMutation, pvMutation); 652 772 653 773 /* Just move the residual data to the front. */ … … 669 789 size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, offStart, pMutationParent->cbInput - 1); 670 790 671 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/ );791 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/, NULL); 672 792 if (RT_LIKELY(pMutation)) 673 793 { … … 683 803 684 804 685 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 805 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 686 806 uint8_t *pbBuf, size_t cbBuf) 687 807 { 688 RT_NOREF(pThis );808 RT_NOREF(pThis, pvMutation); 689 809 Assert(pMutation->pMutationParent->cbInput > pMutation->cbInput); 690 810 size_t cbDel = pMutation->pMutationParent->cbInput - pMutation->cbInput; … … 791 911 { 792 912 PCRTFUZZMUTATION pMutation = pThis->apMutations[i]; 793 pMutation->pMutator->pfnExec(pThis->pFuzzer, pMutation, pbBuf + pMutation->offMutation, 913 pMutation->pMutator->pfnExec(pThis->pFuzzer, pMutation, (void *)&pMutation->abMutation[0], 914 pbBuf + pMutation->offMutation, 794 915 cbInputNow - pMutation->offMutation); 795 916 … … 814 935 815 936 816 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState)937 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, PFNRTFUZZCTXIMPORT pfnImport, void *pvUser) 817 938 { 818 939 AssertPtrReturn(phFuzzCtx, VERR_INVALID_POINTER); 819 AssertPtrReturn(pvState, VERR_INVALID_POINTER); 820 AssertReturn(cbState > 0, VERR_INVALID_PARAMETER); 940 AssertPtrReturn(pfnImport, VERR_INVALID_POINTER); 821 941 822 942 #if 0 … … 897 1017 return rc; 898 1018 #else 1019 RT_NOREF(pvUser); 899 1020 return VERR_NOT_IMPLEMENTED; 900 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; 901 1032 } 902 1033 … … 912 1043 if (RT_SUCCESS(rc)) 913 1044 { 914 rc = RTFuzzCtxCreateFromState (phFuzzCtx, pv, cb);1045 rc = RTFuzzCtxCreateFromStateMem(phFuzzCtx, pv, cb); 915 1046 RTFileReadAllFree(pv, cb); 916 1047 } … … 947 1078 948 1079 949 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) 950 1177 { 951 1178 PRTFUZZCTXINT pThis = hFuzzCtx; … … 954 1181 AssertPtrReturn(pcbState, VERR_INVALID_POINTER); 955 1182 956 #if 0957 char aszPrngExport[_4K]; /* Should be plenty of room here. */958 size_t cbPrng = sizeof(aszPrngExport);959 int rc = RTRandAdvSaveState(pThis->hRand, &aszPrngExport[0], &cbPrng);960 if (RT_SUCCESS(rc))961 {962 RTFUZZCTXSTATE StateExport;963 964 StateExport.u32Magic = RT_H2LE_U32(RTFUZZCTX_MAGIC);965 StateExport.cbPrng = RT_H2LE_U32((uint32_t)cbPrng);966 StateExport.cInputs = RT_H2LE_U32(pThis->cInputs);967 StateExport.fFlagsBehavioral = RT_H2LE_U32(pThis->fFlagsBehavioral);968 StateExport.cbInputMax = RT_H2LE_U64(pThis->cbInputMax);969 970 /* Estimate the size of the required state. */971 size_t cbState = sizeof(StateExport)972 + cbPrng973 + pThis->cInputs * ((pThis->cbInputMax < _1M ? pThis->cbInputMax : _64K) + sizeof(uint32_t)); /* For the size indicator before each input. */974 uint8_t *pbState = (uint8_t *)RTMemAllocZ(cbState);975 if (RT_LIKELY(pbState))976 {977 size_t offState = 0;978 memcpy(pbState, &StateExport, sizeof(StateExport));979 offState += sizeof(StateExport);980 memcpy(&pbState[offState], &aszPrngExport[0], cbPrng);981 offState += cbPrng;982 983 /* Export each input. */984 PRTFUZZINPUTINT pIt;985 RTListForEach(&pThis->LstInputs, pIt, RTFUZZINPUTINT, NdInputs)986 {987 /* Ensure buffer size. */988 if (offState + pIt->cbInput + sizeof(uint32_t) > cbState)989 {990 uint8_t *pbStateNew = (uint8_t *)RTMemRealloc(pbState, cbState + pIt->cbInput + sizeof(uint32_t));991 if (RT_LIKELY(pbStateNew))992 {993 pbState = pbStateNew;994 cbState += pIt->cbInput + sizeof(uint32_t);995 }996 else997 {998 rc = VERR_NO_MEMORY;999 break;1000 }1001 }1002 1003 *(uint32_t *)&pbState[offState] = RT_H2LE_U32((uint32_t)pIt->cbInput);1004 offState += sizeof(uint32_t);1005 memcpy(&pbState[offState], &pIt->abInput[0], pIt->cbInput);1006 offState += pIt->cbInput;1007 }1008 1009 if (RT_SUCCESS(rc))1010 {1011 *ppvState = pbState;1012 *pcbState = offState;1013 }1014 else1015 RTMemFree(pbState);1016 }1017 else1018 rc = VERR_NO_MEMORY;1019 }1020 1021 return rc;1022 #else1023 1183 return VERR_NOT_IMPLEMENTED; 1024 #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); 1025 1196 } 1026 1197 … … 1032 1203 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 1033 1204 1034 void *pvState = NULL; 1035 size_t cbState = 0; 1036 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); 1037 1207 if (RT_SUCCESS(rc)) 1038 1208 { 1039 RTFILE hFile; 1040 1041 rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1042 if (RT_SUCCESS(rc)) 1043 { 1044 rc = RTFileWrite(hFile, pvState, cbState, NULL); 1045 RTFileClose(hFile); 1046 if (RT_FAILURE(rc)) 1047 RTFileDelete(pszFilename); 1048 } 1049 1050 RTMemFree(pvState); 1209 rc = RTFuzzCtxStateExport(hFuzzCtx, rtFuzzCtxStateExportFile, hFile); 1210 RTFileClose(hFile); 1211 if (RT_FAILURE(rc)) 1212 RTFileDelete(pszFilename); 1051 1213 } 1052 1214 … … 1063 1225 1064 1226 int rc = VINF_SUCCESS; 1065 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbInput); 1227 void *pvCorpus = NULL; 1228 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbInput, &pvCorpus); 1066 1229 if (RT_LIKELY(pMutation)) 1067 1230 { 1068 1231 pMutation->pMutator = &g_MutatorCorpus; 1069 1232 pMutation->cbInput = cbInput; 1070 memcpy( &pMutation->u.abCorpus[0], pvInput, cbInput);1233 memcpy(pvCorpus, pvInput, cbInput); 1071 1234 rc = rtFuzzCtxMutationAdd(pThis, pMutation); 1072 1235 if (RT_FAILURE(rc)) … … 1106 1269 1107 1270 uint64_t cbFile = 0; 1271 void *pvCorpus = NULL; 1108 1272 int rc = RTVfsFileGetSize(hVfsFile, &cbFile); 1109 1273 if (RT_SUCCESS(rc)) 1110 1274 { 1111 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile );1275 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile, &pvCorpus); 1112 1276 if (RT_LIKELY(pMutation)) 1113 1277 { 1114 1278 pMutation->pMutator = &g_MutatorCorpus; 1115 1279 pMutation->cbInput = cbFile; 1116 rc = RTVfsFileRead(hVfsFile, &pMutation->u.abCorpus[0], cbFile, NULL);1280 rc = RTVfsFileRead(hVfsFile, pvCorpus, cbFile, NULL); 1117 1281 if (RT_SUCCESS(rc)) 1118 1282 rc = rtFuzzCtxMutationAdd(pThis, pMutation);
Note:
See TracChangeset
for help on using the changeset viewer.