VirtualBox

Changeset 77512 in vbox for trunk


Ignore:
Timestamp:
Feb 28, 2019 7:30:28 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129112
Message:

Backout r129111, something has gone horribly wrong here

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fuzz/fuzz.cpp

    r77511 r77512  
    8787 * @param   pThis               The fuzzer context instance.
    8888 * @param   pMutation           The mutation to work on.
     89 * @param   pvMutation          Mutation dependent data.
    8990 * @param   pbBuf               The buffer to work on.
    9091 * @param   cbBuf               Size of the remaining buffer.
    9192 */
    92 typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXEC(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     93typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXEC(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    9394                                                 uint8_t *pbBuf, size_t cbBuf);
    9495/** Pointer to a mutator execution callback. */
    9596typedef 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 */
     109typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATOREXPORT(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
     110                                                   PFNRTFUZZCTXEXPORT pfnExport, void *pvUser);
     111/** Pointer to a mutator export callback. */
     112typedef 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 */
     125typedef DECLCALLBACK(int) FNRTFUZZCTXMUTATORIMPORT(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, void *pvMutation,
     126                                                   PFNRTFUZZCTXIMPORT pfnImport, void *pvUser);
     127/** Pointer to a mutator import callback. */
     128typedef FNRTFUZZCTXMUTATORIMPORT *PFNRTFUZZCTXMUTATORIMPORT;
    96129
    97130
     
    105138    /** Mutator description. */
    106139    const char                  *pszDesc;
     140    /** Mutator index. */
     141    uint32_t                    uMutator;
    107142    /** Additional flags for the mutator, controlling the behavior. */
    108143    uint64_t                    fFlags;
     
    111146    /** The execution callback. */
    112147    PFNRTFUZZCTXMUTATOREXEC     pfnExec;
     148    /** The export callback. */
     149    PFNRTFUZZCTXMUTATOREXPORT   pfnExport;
     150    /** The import callback. */
     151    PFNRTFUZZCTXMUTATORIMPORT   pfnImport;
    113152} RTFUZZMUTATOR;
    114153/** Pointer to a fuzzing mutator descriptor. */
     
    116155/** Pointer to a const fuzzing mutator descriptor. */
    117156typedef const RTFUZZMUTATOR *PCRTFUZZMUTATOR;
     157
     158/** The special corpus mutator. */
     159#define RTFUZZMUTATOR_ID_CORPUS             UINT32_C(0xffffffff)
    118160
    119161/** Mutator always works from the end of the buffer (no starting offset generation). */
     
    146188    /** Size of the generated input data in bytes after the mutation was applied. */
    147189    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];
    160194} RTFUZZMUTATION;
    161195
     
    242276    /** Magic value for identification. */
    243277    uint32_t                    u32Magic;
     278    /** Context type. */
     279    uint32_t                    uCtxType;
    244280    /** Size of the PRNG state following in bytes. */
    245281    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;
    248286    /** Behavioral flags. */
    249287    uint32_t                    fFlagsBehavioral;
     
    253291/** Pointer to a fuzzing context state. */
    254292typedef 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 */
     303typedef 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;
    255322
    256323
     
    276343
    277344
     345/**
     346 * Fuzzing context export AVL arguments.
     347 */
     348typedef 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. */
     356typedef RTFUZZEXPORTARGS *PRTFUZZEXPORTARGS;
     357/** Pointer to the constant export arguments. */
     358typedef const RTFUZZEXPORTARGS *PCRTFUZZEXPORTARGS;
     359
    278360
    279361/*********************************************************************************************************************************
     
    291373                                                                PPRTFUZZMUTATION ppMutation);
    292374
    293 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     375static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    294376                                                    uint8_t *pbBuf, size_t cbBuf);
    295 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     377static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    296378                                                     uint8_t *pbBuf, size_t cbBuf);
    297 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     379static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    298380                                                         uint8_t *pbBuf, size_t cbBuf);
    299 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     381static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    300382                                                                      uint8_t *pbBuf, size_t cbBuf);
    301 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     383static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    302384                                                        uint8_t *pbBuf, size_t cbBuf);
    303 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     385static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    304386                                                                uint8_t *pbBuf, size_t cbBuf);
    305387
     388static DECLCALLBACK(int) rtFuzzCtxMutatorExportDefault(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
     389                                                       PFNRTFUZZCTXEXPORT pfnExport, void *pvUser);
     390static DECLCALLBACK(int) rtFuzzCtxMutatorImportDefault(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, void *pvMutation,
     391                                                      PFNRTFUZZCTXIMPORT pfnImport, void *pvUser);
    306392
    307393/*********************************************************************************************************************************
     
    317403    /** pszDesc */
    318404    "Special mutator, which is assigned to the initial corpus",
     405    /** uMutator. */
     406    RTFUZZMUTATOR_ID_CORPUS,
    319407    /** fFlags */
    320408    RTFUZZMUTATOR_F_DEFAULT,
     
    322410    NULL,
    323411    /** pfnExec */
    324     rtFuzzCtxMutatorCorpusExec
     412    rtFuzzCtxMutatorCorpusExec,
     413    /** pfnExport */
     414    rtFuzzCtxMutatorExportDefault,
     415    /** pfnImport */
     416    rtFuzzCtxMutatorImportDefault
    325417};
    326418
     
    330422static RTFUZZMUTATOR const g_aMutators[] =
    331423{
    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                          }
    339431};
    340432
     
    390482}
    391483
    392 
    393484#if 0 /* unused */
    394485/**
     
    406497#endif
    407498
    408 
    409499/**
    410500 * Adds the given mutation to the corpus of the given fuzzer context.
     
    418508    int rc = VINF_SUCCESS;
    419509
    420     pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations) - 1;
     510    pMutation->Core.Key = ASMAtomicIncU64(&pThis->cMutations);
    421511    rc = RTSemRWRequestWrite(pThis->hSemRwMutations, RT_INDEFINITE_WAIT);
    422512    AssertRC(rc); RT_NOREF(rc);
     
    467557 * @param   pMutationParent     The parent mutation, can be NULL.
    468558 * @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 */
     561static PRTFUZZMUTATION rtFuzzMutationCreate(PRTFUZZCTXINT pThis, uint64_t offMutation, PRTFUZZMUTATION pMutationParent,
     562                                            size_t cbAdditional, void **ppvMutation)
    471563{
    472564    PRTFUZZMUTATION pMutation = (PRTFUZZMUTATION)rtFuzzCtxMemoryAlloc(pThis, sizeof(RTFUZZMUTATION) + cbAdditional);
     
    479571        pMutation->offMutation     = offMutation;
    480572        pMutation->pMutationParent = pMutationParent;
     573        pMutation->cbMutation      = cbAdditional;
    481574
    482575        if (pMutationParent)
    483576            pMutation->iLvl = pMutationParent->iLvl + 1;
     577        if (ppvMutation)
     578            *ppvMutation = &pMutation->abMutation[0];
    484579    }
    485580
     
    512607
    513608
    514 static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     609/**
     610 * Default mutator export callback (just writing the raw data).
     611 */
     612static 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 */
     622static 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
     629static DECLCALLBACK(int) rtFuzzCtxMutatorCorpusExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    515630                                                    uint8_t *pbBuf, size_t cbBuf)
    516631{
    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);
    519634    return VINF_SUCCESS;
    520635}
     
    528643{
    529644    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);
    531647    if (RT_LIKELY(pMutation))
    532648    {
    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);
     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);
    535651        *ppMutation = pMutation;
    536652    }
     
    542658
    543659
    544 static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     660static DECLCALLBACK(int) rtFuzzCtxMutatorBitFlipExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    545661                                                     uint8_t *pbBuf, size_t cbBuf)
    546662{
    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);
    549666    return VINF_SUCCESS;
    550667}
     
    558675{
    559676    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);
    561679    if (RT_LIKELY(pMutation))
    562680    {
    563681        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. */
    565683        *ppMutation = pMutation;
    566684    }
     
    572690
    573691
    574 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     692static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    575693                                                         uint8_t *pbBuf, size_t cbBuf)
    576694{
    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;
    579698    return VINF_SUCCESS;
    580699}
     
    592711        size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, pMutationParent->cbInput + 1, pThis->cbInputMax);
    593712        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);
    596716        if (RT_LIKELY(pMutation))
    597717        {
    598718            pMutation->cbInput = cbInputMutated;
    599             RTRandAdvBytes(pThis->hRand, &pMutation->u.abAdd[0], cbInsert);
     719            RTRandAdvBytes(pThis->hRand, pbAdd, cbInsert);
    600720            *ppMutation = pMutation;
    601721        }
     
    608728
    609729
    610 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     730static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    611731                                                                      uint8_t *pbBuf, size_t cbBuf)
    612732{
     
    618738        memmove(pbBuf + cbInsert, pbBuf, cbBuf);
    619739
    620     memcpy(pbBuf, &pMutation->u.abAdd[0], cbInsert);
     740    memcpy(pbBuf, pvMutation, cbInsert);
    621741    return VINF_SUCCESS;
    622742}
     
    632752    if (pMutationParent->cbInput - offStart >= 1)
    633753    {
    634         PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/);
     754        PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/, NULL);
    635755        if (RT_LIKELY(pMutation))
    636756        {
     
    646766
    647767
    648 static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     768static DECLCALLBACK(int) rtFuzzCtxMutatorByteDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    649769                                                        uint8_t *pbBuf, size_t cbBuf)
    650770{
    651     RT_NOREF(pThis, pMutation);
     771    RT_NOREF(pThis, pMutation, pvMutation);
    652772
    653773    /* Just move the residual data to the front. */
     
    669789        size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, offStart, pMutationParent->cbInput - 1);
    670790
    671         PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/);
     791        PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 0 /*cbAdditional*/, NULL);
    672792        if (RT_LIKELY(pMutation))
    673793        {
     
    683803
    684804
    685 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation,
     805static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceDeleteExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation,
    686806                                                                uint8_t *pbBuf, size_t cbBuf)
    687807{
    688     RT_NOREF(pThis);
     808    RT_NOREF(pThis, pvMutation);
    689809    Assert(pMutation->pMutationParent->cbInput > pMutation->cbInput);
    690810    size_t cbDel = pMutation->pMutationParent->cbInput - pMutation->cbInput;
     
    791911        {
    792912            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,
    794915                                         cbInputNow - pMutation->offMutation);
    795916
     
    814935
    815936
    816 RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, const void *pvState, size_t cbState)
     937RTDECL(int) RTFuzzCtxCreateFromState(PRTFUZZCTX phFuzzCtx, PFNRTFUZZCTXIMPORT pfnImport, void *pvUser)
    817938{
    818939    AssertPtrReturn(phFuzzCtx, VERR_INVALID_POINTER);
    819     AssertPtrReturn(pvState, VERR_INVALID_POINTER);
    820     AssertReturn(cbState > 0, VERR_INVALID_PARAMETER);
     940    AssertPtrReturn(pfnImport, VERR_INVALID_POINTER);
    821941
    822942#if 0
     
    8971017    return rc;
    8981018#else
     1019    RT_NOREF(pvUser);
    8991020    return VERR_NOT_IMPLEMENTED;
    9001021#endif
     1022}
     1023
     1024
     1025RTDECL(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;
    9011032}
    9021033
     
    9121043    if (RT_SUCCESS(rc))
    9131044    {
    914         rc = RTFuzzCtxCreateFromState(phFuzzCtx, pv, cb);
     1045        rc = RTFuzzCtxCreateFromStateMem(phFuzzCtx, pv, cb);
    9151046        RTFileReadAllFree(pv, cb);
    9161047    }
     
    9471078
    9481079
    949 RTDECL(int) RTFuzzCtxStateExport(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState)
     1080/**
     1081 * Fuzzing context export callback for a single mutation.
     1082 */
     1083static 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
     1110RTDECL(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
     1176RTDECL(int) RTFuzzCtxStateExportToMem(RTFUZZCTX hFuzzCtx, void **ppvState, size_t *pcbState)
    9501177{
    9511178    PRTFUZZCTXINT pThis = hFuzzCtx;
     
    9541181    AssertPtrReturn(pcbState, VERR_INVALID_POINTER);
    9551182
    956 #if 0
    957     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                          + 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
    10231183    return VERR_NOT_IMPLEMENTED;
    1024 #endif
     1184}
     1185
     1186
     1187/**
     1188 * Export to file callback.
     1189 */
     1190DECLCALLBACK(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);
    10251196}
    10261197
     
    10321203    AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
    10331204
    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);
    10371207    if (RT_SUCCESS(rc))
    10381208    {
    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);
    10511213    }
    10521214
     
    10631225
    10641226    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);
    10661229    if (RT_LIKELY(pMutation))
    10671230    {
    10681231        pMutation->pMutator = &g_MutatorCorpus;
    10691232        pMutation->cbInput  = cbInput;
    1070         memcpy(&pMutation->u.abCorpus[0], pvInput, cbInput);
     1233        memcpy(pvCorpus, pvInput, cbInput);
    10711234        rc = rtFuzzCtxMutationAdd(pThis, pMutation);
    10721235        if (RT_FAILURE(rc))
     
    11061269
    11071270    uint64_t cbFile = 0;
     1271    void *pvCorpus = NULL;
    11081272    int rc = RTVfsFileGetSize(hVfsFile, &cbFile);
    11091273    if (RT_SUCCESS(rc))
    11101274    {
    1111         PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile);
     1275        PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, 0, NULL, cbFile, &pvCorpus);
    11121276        if (RT_LIKELY(pMutation))
    11131277        {
    11141278            pMutation->pMutator = &g_MutatorCorpus;
    11151279            pMutation->cbInput  = cbFile;
    1116             rc = RTVfsFileRead(hVfsFile, &pMutation->u.abCorpus[0], cbFile, NULL);
     1280            rc = RTVfsFileRead(hVfsFile, pvCorpus, cbFile, NULL);
    11171281            if (RT_SUCCESS(rc))
    11181282                rc = rtFuzzCtxMutationAdd(pThis, pMutation);
Note: See TracChangeset for help on using the changeset viewer.

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