- Timestamp:
- Feb 28, 2019 7:21:30 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fuzz/fuzz.cpp
r77509 r77511 87 87 * @param pThis The fuzzer context instance. 88 88 * @param pMutation The mutation to work on. 89 * @param pvMutation Mutation dependent data.90 89 * @param pbBuf The buffer to work on. 91 90 * @param cbBuf Size of the remaining buffer. 92 91 */ 93 typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXEC(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,92 typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXEC(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 94 93 uint8_t *pbBuf, size_t cbBuf); 95 94 /** Pointer to a mutator execution callback. */ 96 95 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;129 96 130 97 … … 138 105 /** Mutator description. */ 139 106 const char *pszDesc; 140 /** Mutator index. */141 uint32_t uMutator;142 107 /** Additional flags for the mutator, controlling the behavior. */ 143 108 uint64_t fFlags; … … 146 111 /** The execution callback. */ 147 112 PFNRTFUZZCTXMUTATOREXEC pfnExec; 148 /** The export callback. */149 PFNRTFUZZCTXMUTATOREXPORT pfnExport;150 /** The import callback. */151 PFNRTFUZZCTXMUTATORIMPORT pfnImport;152 113 } RTFUZZMUTATOR; 153 114 /** Pointer to a fuzzing mutator descriptor. */ … … 155 116 /** Pointer to a const fuzzing mutator descriptor. */ 156 117 typedef const RTFUZZMUTATOR *PCRTFUZZMUTATOR; 157 158 /** The special corpus mutator. */159 #define RTFUZZMUTATOR_ID_CORPUS UINT32_C(0xffffffff)160 118 161 119 /** Mutator always works from the end of the buffer (no starting offset generation). */ … … 188 146 /** Size of the generated input data in bytes after the mutation was applied. */ 189 147 size_t cbInput; 190 /** Size of the mutation dependent data. */ 191 size_t cbMutation; 192 /** Mutation dependent data, variable in size. */ 193 uint8_t abMutation[1]; 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; 194 160 } RTFUZZMUTATION; 195 161 … … 276 242 /** Magic value for identification. */ 277 243 uint32_t u32Magic; 278 /** Context type. */279 uint32_t uCtxType;280 244 /** Size of the PRNG state following in bytes. */ 281 245 uint32_t cbPrng; 282 /** Number of mutator descriptors following. */ 283 uint32_t cMutators; 284 /** Number of mutation descriptors following. */ 285 uint32_t cMutations; 246 /** Number of input descriptors following. */ 247 uint32_t cInputs; 286 248 /** Behavioral flags. */ 287 249 uint32_t fFlagsBehavioral; … … 291 253 /** Pointer to a fuzzing context state. */ 292 254 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 RTFUZZMUTATIONSTATE304 {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;322 255 323 256 … … 343 276 344 277 345 /**346 * Fuzzing context export AVL arguments.347 */348 typedef struct RTFUZZEXPORTARGS349 {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 360 278 361 279 /********************************************************************************************************************************* … … 373 291 PPRTFUZZMUTATION ppMutation); 374 292 375 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,293 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 376 294 uint8_t *pbBuf, size_t cbBuf); 377 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,295 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 378 296 uint8_t *pbBuf, size_t cbBuf); 379 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,297 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 380 298 uint8_t *pbBuf, size_t cbBuf); 381 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,299 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 382 300 uint8_t *pbBuf, size_t cbBuf); 383 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,301 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 384 302 uint8_t *pbBuf, size_t cbBuf); 385 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,303 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 386 304 uint8_t *pbBuf, size_t cbBuf); 387 305 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);392 306 393 307 /********************************************************************************************************************************* … … 403 317 /** pszDesc */ 404 318 "Special mutator, which is assigned to the initial corpus", 405 /** uMutator. */406 RTFUZZMUTATOR_ID_CORPUS,407 319 /** fFlags */ 408 320 RTFUZZMUTATOR_F_DEFAULT, … … 410 322 NULL, 411 323 /** pfnExec */ 412 rtFuzzCtxMutatorCorpusExec, 413 /** pfnExport */ 414 rtFuzzCtxMutatorExportDefault, 415 /** pfnImport */ 416 rtFuzzCtxMutatorImportDefault 324 rtFuzzCtxMutatorCorpusExec 417 325 }; 418 326 … … 422 330 static RTFUZZMUTATOR const g_aMutators[] = 423 331 { 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}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} 431 339 }; 432 340 … … 482 390 } 483 391 392 484 393 #if 0 /* unused */ 485 394 /** … … 497 406 #endif 498 407 408 499 409 /** 500 410 * Adds the given mutation to the corpus of the given fuzzer context. … … 508 418 int rc = VINF_SUCCESS; 509 419 510 pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations) ;420 pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations) - 1; 511 421 rc = RTSemRWRequestWrite(pThis->hSemRwMutations, RT_INDEFINITE_WAIT); 512 422 AssertRC(rc); RT_NOREF(rc); … … 557 467 * @param pMutationParent The parent mutation, can be NULL. 558 468 * @param cbAdditional Additional number of bytes to allocate after the core structure. 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 */ 470 static PRTFUZZMUTATION rtFuzzMutationCreate(PRTFUZZCTXINT pThis, uint64_t offMutation, PRTFUZZMUTATION pMutationParent, size_t cbAdditional) 563 471 { 564 472 PRTFUZZMUTATION pMutation = (PRTFUZZMUTATION)rtFuzzCtxMemoryAlloc(pThis, sizeof(RTFUZZMUTATION) + cbAdditional); … … 571 479 pMutation->offMutation = offMutation; 572 480 pMutation->pMutationParent = pMutationParent; 573 pMutation->cbMutation = cbAdditional;574 481 575 482 if (pMutationParent) 576 483 pMutation->iLvl = pMutationParent->iLvl + 1; 577 if (ppvMutation)578 *ppvMutation = &pMutation->abMutation[0];579 484 } 580 485 … … 607 512 608 513 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, 514 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 630 515 uint8_t *pbBuf, size_t cbBuf) 631 516 { 632 RT_NOREF(pThis, cbBuf , pvMutation);633 memcpy(pbBuf, pvMutation, pMutation->cbInput);517 RT_NOREF(pThis, cbBuf); 518 memcpy(pbBuf, &pMutation->u.abCorpus[0], pMutation->cbInput); 634 519 return VINF_SUCCESS; 635 520 } … … 643 528 { 644 529 int rc = VINF_SUCCESS; 645 uint8_t *pidxBitFlip = 0; 646 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, sizeof(*pidxBitFlip), (void **)&pidxBitFlip); 530 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 647 531 if (RT_LIKELY(pMutation)) 648 532 { 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 pMutation->cbInput = pMutationParent->cbInput; /* Bit flips don't change the input size. */ 534 pMutation->u.idxBitFlip = RTRandAdvS32Ex(pThis->hRand, 0, sizeof(uint8_t) * 8 - 1); 651 535 *ppMutation = pMutation; 652 536 } … … 658 542 659 543 660 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,544 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 661 545 uint8_t *pbBuf, size_t cbBuf) 662 546 { 663 RT_NOREF(pThis, cbBuf, pMutation); 664 uint8_t idxBitFlip = *(uint8_t *)pvMutation; 665 ASMBitToggle(pbBuf, idxBitFlip); 547 RT_NOREF(pThis, cbBuf); 548 ASMBitToggle(pbBuf, pMutation->u.idxBitFlip); 666 549 return VINF_SUCCESS; 667 550 } … … 675 558 { 676 559 int rc = VINF_SUCCESS; 677 uint8_t *pbReplace = 0; 678 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, sizeof(*pbReplace), (void **)&pbReplace); 560 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 679 561 if (RT_LIKELY(pMutation)) 680 562 { 681 563 pMutation->cbInput = pMutationParent->cbInput; /* Byte replacements don't change the input size. */ 682 RTRandAdvBytes(pThis->hRand, pbReplace, 1); /** @todo Filter out same values. */564 RTRandAdvBytes(pThis->hRand, &pMutation->u.bByteReplace, 1); /** @todo Filter out same values. */ 683 565 *ppMutation = pMutation; 684 566 } … … 690 572 691 573 692 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,574 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 693 575 uint8_t *pbBuf, size_t cbBuf) 694 576 { 695 RT_NOREF(pThis, cbBuf, pMutation); 696 uint8_t bReplace = *(uint8_t *)pvMutation; 697 *pbBuf = bReplace; 577 RT_NOREF(pThis, cbBuf); 578 *pbBuf = pMutation->u.bByteReplace; 698 579 return VINF_SUCCESS; 699 580 } … … 711 592 size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, pMutationParent->cbInput + 1, pThis->cbInputMax); 712 593 size_t cbInsert = cbInputMutated - pMutationParent->cbInput; 713 uint8_t *pbAdd = NULL; 714 715 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, cbInsert, (void **)&pbAdd); 594 595 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, cbInsert); 716 596 if (RT_LIKELY(pMutation)) 717 597 { 718 598 pMutation->cbInput = cbInputMutated; 719 RTRandAdvBytes(pThis->hRand, pbAdd, cbInsert);599 RTRandAdvBytes(pThis->hRand, &pMutation->u.abAdd[0], cbInsert); 720 600 *ppMutation = pMutation; 721 601 } … … 728 608 729 609 730 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,610 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 731 611 uint8_t *pbBuf, size_t cbBuf) 732 612 { … … 738 618 memmove(pbBuf + cbInsert, pbBuf, cbBuf); 739 619 740 memcpy(pbBuf, pvMutation, cbInsert);620 memcpy(pbBuf, &pMutation->u.abAdd[0], cbInsert); 741 621 return VINF_SUCCESS; 742 622 } … … 752 632 if (pMutationParent->cbInput - offStart >= 1) 753 633 { 754 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/ , NULL);634 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 755 635 if (RT_LIKELY(pMutation)) 756 636 { … … 766 646 767 647 768 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,648 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 769 649 uint8_t *pbBuf, size_t cbBuf) 770 650 { 771 RT_NOREF(pThis, pMutation , pvMutation);651 RT_NOREF(pThis, pMutation); 772 652 773 653 /* Just move the residual data to the front. */ … … 789 669 size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, offStart, pMutationParent->cbInput - 1); 790 670 791 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/ , NULL);671 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/); 792 672 if (RT_LIKELY(pMutation)) 793 673 { … … 803 683 804 684 805 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,685 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, 806 686 uint8_t *pbBuf, size_t cbBuf) 807 687 { 808 RT_NOREF(pThis , pvMutation);688 RT_NOREF(pThis); 809 689 Assert(pMutation->pMutationParent->cbInput > pMutation->cbInput); 810 690 size_t cbDel = pMutation->pMutationParent->cbInput - pMutation->cbInput; … … 911 791 { 912 792 PCRTFUZZMUTATION pMutation = pThis->apMutations[i]; 913 pMutation->pMutator->pfnExec(pThis->pFuzzer, pMutation, (void *)&pMutation->abMutation[0], 914 pbBuf + pMutation->offMutation, 793 pMutation->pMutator->pfnExec(pThis->pFuzzer, pMutation, pbBuf + pMutation->offMutation, 915 794 cbInputNow - pMutation->offMutation); 916 795 … … 935 814 936 815 937 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, PFNRTFUZZCTXIMPORT pfnImport, void *pvUser)816 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState) 938 817 { 939 818 AssertPtrReturn(phFuzzCtx, VERR_INVALID_POINTER); 940 AssertPtrReturn(pfnImport, VERR_INVALID_POINTER); 819 AssertPtrReturn(pvState, VERR_INVALID_POINTER); 820 AssertReturn(cbState > 0, VERR_INVALID_PARAMETER); 941 821 942 822 #if 0 … … 1017 897 return rc; 1018 898 #else 1019 RT_NOREF(pvUser);1020 899 return VERR_NOT_IMPLEMENTED; 1021 900 #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;1032 901 } 1033 902 … … 1043 912 if (RT_SUCCESS(rc)) 1044 913 { 1045 rc = RTFuzzCtxCreateFromState Mem(phFuzzCtx, pv, cb);914 rc = RTFuzzCtxCreateFromState(phFuzzCtx, pv, cb); 1046 915 RTFileReadAllFree(pv, cb); 1047 916 } … … 1078 947 1079 948 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) 949 RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState) 1111 950 { 1112 951 PRTFUZZCTXINT pThis = hFuzzCtx; 1113 952 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1114 AssertPtrReturn(pfnExport, VERR_INVALID_POINTER); 1115 953 AssertPtrReturn(ppvState, VERR_INVALID_POINTER); 954 AssertPtrReturn(pcbState, VERR_INVALID_POINTER); 955 956 #if 0 1116 957 char aszPrngExport[_4K]; /* Should be plenty of room here. */ 1117 958 size_t cbPrng = sizeof(aszPrngExport); … … 1122 963 1123 964 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 965 StateExport.cbPrng = RT_H2LE_U32((uint32_t)cbPrng); 1137 StateExport.cMutations = RT_H2LE_U32(pThis->cMutations); 1138 StateExport.cMutators = RT_H2LE_U32(pThis->cMutators); 966 StateExport.cInputs = RT_H2LE_U32(pThis->cInputs); 1139 967 StateExport.fFlagsBehavioral = RT_H2LE_U32(pThis->fFlagsBehavioral); 1140 968 StateExport.cbInputMax = RT_H2LE_U64(pThis->cbInputMax); 1141 969 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); 970 /* Estimate the size of the required state. */ 971 size_t cbState = sizeof(StateExport) 972 + cbPrng 973 + 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 else 997 { 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 else 1015 RTMemFree(pbState); 1016 } 1017 else 1018 rc = VERR_NO_MEMORY; 1019 } 1020 1021 return rc; 1022 #else 1023 return VERR_NOT_IMPLEMENTED; 1024 #endif 1025 } 1026 1027 1028 RTDECL(int) RTFuzzCtxStateExportToFile(RTFUZZCTX hFuzzCtx, const char *pszFilename) 1029 { 1030 PRTFUZZCTXINT pThis = hFuzzCtx; 1031 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1032 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 1033 1034 void *pvState = NULL; 1035 size_t cbState = 0; 1036 int rc = RTFuzzCtxStateExport(hFuzzCtx, &pvState, &cbState); 1037 if (RT_SUCCESS(rc)) 1038 { 1039 RTFILE hFile; 1040 1041 rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1146 1042 if (RT_SUCCESS(rc)) 1147 1043 { 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 } 1044 rc = RTFileWrite(hFile, pvState, cbState, NULL); 1045 RTFileClose(hFile); 1046 if (RT_FAILURE(rc)) 1047 RTFileDelete(pszFilename); 1159 1048 } 1160 1049 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) 1177 { 1178 PRTFUZZCTXINT pThis = hFuzzCtx; 1179 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1180 AssertPtrReturn(ppvState, VERR_INVALID_POINTER); 1181 AssertPtrReturn(pcbState, VERR_INVALID_POINTER); 1182 1183 return VERR_NOT_IMPLEMENTED; 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); 1196 } 1197 1198 1199 RTDECL(int) RTFuzzCtxStateExportToFile(RTFUZZCTX hFuzzCtx, const char *pszFilename) 1200 { 1201 PRTFUZZCTXINT pThis = hFuzzCtx; 1202 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1203 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 1204 1205 RTFILE hFile; 1206 int rc = RTFileOpen(&hFile, pszFilename, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1207 if (RT_SUCCESS(rc)) 1208 { 1209 rc = RTFuzzCtxStateExport(hFuzzCtx, rtFuzzCtxStateExportFile, hFile); 1210 RTFileClose(hFile); 1211 if (RT_FAILURE(rc)) 1212 RTFileDelete(pszFilename); 1050 RTMemFree(pvState); 1213 1051 } 1214 1052 … … 1225 1063 1226 1064 int rc = VINF_SUCCESS; 1227 void *pvCorpus = NULL; 1228 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbInput, &pvCorpus); 1065 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbInput); 1229 1066 if (RT_LIKELY(pMutation)) 1230 1067 { 1231 1068 pMutation->pMutator = &g_MutatorCorpus; 1232 1069 pMutation->cbInput = cbInput; 1233 memcpy( pvCorpus, pvInput, cbInput);1070 memcpy(&pMutation->u.abCorpus[0], pvInput, cbInput); 1234 1071 rc = rtFuzzCtxMutationAdd(pThis, pMutation); 1235 1072 if (RT_FAILURE(rc)) … … 1269 1106 1270 1107 uint64_t cbFile = 0; 1271 void *pvCorpus = NULL;1272 1108 int rc = RTVfsFileGetSize(hVfsFile, &cbFile); 1273 1109 if (RT_SUCCESS(rc)) 1274 1110 { 1275 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile , &pvCorpus);1111 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile); 1276 1112 if (RT_LIKELY(pMutation)) 1277 1113 { 1278 1114 pMutation->pMutator = &g_MutatorCorpus; 1279 1115 pMutation->cbInput = cbFile; 1280 rc = RTVfsFileRead(hVfsFile, pvCorpus, cbFile, NULL);1116 rc = RTVfsFileRead(hVfsFile, &pMutation->u.abCorpus[0], cbFile, NULL); 1281 1117 if (RT_SUCCESS(rc)) 1282 1118 rc = rtFuzzCtxMutationAdd(pThis, pMutation);
Note:
See TracChangeset
for help on using the changeset viewer.