Changeset 77564 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Mar 5, 2019 10:30:33 AM (6 years ago)
- Location:
- trunk/src/VBox/Runtime/common/fuzz
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fuzz/fuzz.cpp
r77544 r77564 368 368 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplacePrep(PRTFUZZCTXINT pThis, uint64_t offStart, PRTFUZZMUTATION pMutationParent, 369 369 PPRTFUZZMUTATION ppMutation); 370 static DECLCALLBACK(int) rtFuzzCtxMutatorByteInsertPrep(PRTFUZZCTXINT pThis, uint64_t offStart, PRTFUZZMUTATION pMutationParent, 371 PPRTFUZZMUTATION ppMutation); 370 372 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendPrep(PRTFUZZCTXINT pThis, uint64_t offStart, PRTFUZZMUTATION pMutationParent, 371 373 PPRTFUZZMUTATION ppMutation); … … 381 383 static DECLCALLBACK(int) rtFuzzCtxMutatorByteReplaceExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 382 384 uint8_t *pbBuf, size_t cbBuf); 385 static DECLCALLBACK(int) rtFuzzCtxMutatorByteInsertExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 386 uint8_t *pbBuf, size_t cbBuf); 383 387 static DECLCALLBACK(int) rtFuzzCtxMutatorByteSequenceInsertAppendExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 384 388 uint8_t *pbBuf, size_t cbBuf); … … 425 429 static RTFUZZMUTATOR const g_aMutators[] = 426 430 { 427 /* pszId pszDesc uMutator fFlags pfnPrep pfnExec pfnExport 431 /* pszId pszDesc uMutator fFlags pfnPrep pfnExec pfnExport pfnImport */ 428 432 { "BitFlip", "Flips a single bit in the input", 0, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorBitFlipPrep, rtFuzzCtxMutatorBitFlipExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 429 433 { "ByteReplace", "Replaces a single byte in the input", 1, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteReplacePrep, rtFuzzCtxMutatorByteReplaceExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 430 { "ByteSeqIns", "Inserts a byte sequence in the input", 2, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 431 { "ByteSeqApp", "Appends a byte sequence to the input", 3, RTFUZZMUTATOR_F_END_OF_BUF, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 432 { "ByteDelete", "Deletes a single byte sequence from the input", 4, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteDeletePrep, rtFuzzCtxMutatorByteDeleteExec, NULL, NULL }, 433 { "ByteSeqDel", "Deletes a byte sequence from the input", 5, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceDeletePrep, rtFuzzCtxMutatorByteSequenceDeleteExec, NULL, NULL } 434 { "ByteInsert", "Inserts a single byte sequence into the input", 2, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteInsertPrep, rtFuzzCtxMutatorByteInsertExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 435 { "ByteSeqIns", "Inserts a byte sequence in the input", 3, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 436 { "ByteSeqApp", "Appends a byte sequence to the input", 4, RTFUZZMUTATOR_F_END_OF_BUF, rtFuzzCtxMutatorByteSequenceInsertAppendPrep, rtFuzzCtxMutatorByteSequenceInsertAppendExec, rtFuzzCtxMutatorExportDefault, rtFuzzCtxMutatorImportDefault }, 437 { "ByteDelete", "Deletes a single byte sequence from the input", 5, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteDeletePrep, rtFuzzCtxMutatorByteDeleteExec, NULL, NULL }, 438 { "ByteSeqDel", "Deletes a byte sequence from the input", 6, RTFUZZMUTATOR_F_DEFAULT, rtFuzzCtxMutatorByteSequenceDeletePrep, rtFuzzCtxMutatorByteSequenceDeleteExec, NULL, NULL } 434 439 }; 435 440 … … 705 710 uint8_t bReplace = *(uint8_t *)pvMutation; 706 711 *pbBuf = bReplace; 712 return VINF_SUCCESS; 713 } 714 715 716 /** 717 * Mutator callback - inserts a single byte into the input. 718 */ 719 static DECLCALLBACK(int) rtFuzzCtxMutatorByteInsertPrep(PRTFUZZCTXINT pThis, uint64_t offStart, PRTFUZZMUTATION pMutationParent, 720 PPRTFUZZMUTATION ppMutation) 721 { 722 int rc = VINF_SUCCESS; 723 uint8_t *pbInsert = 0; 724 if (pMutationParent->cbInput < pThis->cbInputMax) 725 { 726 PRTFUZZMUTATION pMutation = rtFuzzMutationCreate(pThis, offStart, pMutationParent, 1 /*cbAdditional*/, (void **)&pbInsert); 727 if (RT_LIKELY(pMutation)) 728 { 729 pMutation->cbInput = pMutationParent->cbInput + 1; 730 RTRandAdvBytes(pThis->hRand, pbInsert, 1); 731 *ppMutation = pMutation; 732 } 733 else 734 rc = VERR_NO_MEMORY; 735 } 736 737 return rc; 738 } 739 740 741 static DECLCALLBACK(int) rtFuzzCtxMutatorByteInsertExec(PRTFUZZCTXINT pThis, PCRTFUZZMUTATION pMutation, const void *pvMutation, 742 uint8_t *pbBuf, size_t cbBuf) 743 { 744 RT_NOREF(pThis, pMutation, pvMutation); 745 746 /* Just move the residual data one byte to the back. */ 747 memmove(pbBuf + 1, pbBuf, cbBuf); 748 *pbBuf = *(uint8_t *)pvMutation; 707 749 return VINF_SUCCESS; 708 750 } … … 794 836 { 795 837 int rc = VINF_SUCCESS; 796 if (pMutationParent->cbInput > 1)838 if (pMutationParent->cbInput > offStart) 797 839 { 798 840 size_t cbInputMutated = (size_t)RTRandAdvU64Ex(pThis->hRand, offStart, pMutationParent->cbInput - 1); -
trunk/src/VBox/Runtime/common/fuzz/fuzzclientcmd.cpp
r77509 r77564 35 35 #include <iprt/buildconfig.h> 36 36 #include <iprt/errcore.h> 37 #include <iprt/file.h> 37 38 #include <iprt/getopt.h> 39 #include <iprt/ldr.h> 38 40 #include <iprt/mem.h> 39 41 #include <iprt/message.h> … … 44 46 45 47 48 49 typedef DECLCALLBACK(int) FNLLVMFUZZERTESTONEINPUT(const uint8_t *pbData, size_t cbData); 50 typedef FNLLVMFUZZERTESTONEINPUT *PFNLLVMFUZZERTESTONEINPUT; 51 52 46 53 /** 47 54 * Fuzzing client command state. … … 50 57 { 51 58 /** Our own fuzzing context containing all the data. */ 52 RTFUZZCTX hFuzzCtx;59 RTFUZZCTX hFuzzCtx; 53 60 /** Consumption callback. */ 54 PFNFUZZCLIENTCONSUME pfnConsume;61 PFNFUZZCLIENTCONSUME pfnConsume; 55 62 /** Opaque user data to pass to the consumption callback. */ 56 void *pvUser; 63 void *pvUser; 64 /** The LLVM libFuzzer compatible entry point if configured */ 65 PFNLLVMFUZZERTESTONEINPUT pfnLlvmFuzzerTestOneInput; 66 /** The selected input channel. */ 67 RTFUZZOBSINPUTCHAN enmInputChan; 57 68 /** Standard input VFS handle. */ 58 RTVFSIOSTREAM hVfsStdIn;69 RTVFSIOSTREAM hVfsStdIn; 59 70 /** Standard output VFS handle. */ 60 RTVFSIOSTREAM hVfsStdOut;71 RTVFSIOSTREAM hVfsStdOut; 61 72 } RTFUZZCMDCLIENT; 62 73 /** Pointer to a fuzzing client command state. */ 63 74 typedef RTFUZZCMDCLIENT *PRTFUZZCMDCLIENT; 75 76 77 78 /** 79 * Runs the appropriate consumption callback with the provided data. 80 * 81 * @returns Status code, 0 for success. 82 * @param pThis The fuzzing client command state. 83 * @param pvData The data to consume. 84 * @param cbData Size of the data in bytes. 85 */ 86 static int rtFuzzCmdClientConsume(PRTFUZZCMDCLIENT pThis, const void *pvData, size_t cbData) 87 { 88 if (pThis->pfnLlvmFuzzerTestOneInput) 89 return pThis->pfnLlvmFuzzerTestOneInput((const uint8_t *)pvData, cbData); 90 else 91 return pThis->pfnConsume(pvData, cbData, pThis->pvUser); 92 } 64 93 65 94 … … 89 118 { 90 119 char bResp = '.'; 91 int rc2 = pThis->pfnConsume(pv, cb, pThis->pvUser);120 int rc2 = rtFuzzCmdClientConsume(pThis, pv, cb); 92 121 if (RT_SUCCESS(rc2)) 93 122 { … … 153 182 154 183 184 /** 185 * Run a single iteration of the fuzzing client and return. 186 * 187 * @returns Process exit status. 188 * @param pThis The fuzzing client command state. 189 */ 190 static RTEXITCODE rtFuzzCmdClientRunFile(PRTFUZZCMDCLIENT pThis, const char *pszFilename) 191 { 192 void *pv = NULL; 193 size_t cbFile = 0; 194 int rc = RTFileReadAll(pszFilename, &pv, &cbFile); 195 if (RT_SUCCESS(rc)) 196 { 197 rtFuzzCmdClientConsume(pThis, pv, cbFile); 198 RTFileReadAllFree(pv, cbFile); 199 return RTEXITCODE_SUCCESS; 200 } 201 202 return RTEXITCODE_FAILURE; 203 } 204 205 155 206 RTR3DECL(RTEXITCODE) RTFuzzCmdFuzzingClient(unsigned cArgs, char **papszArgs, PFNFUZZCLIENTCONSUME pfnConsume, void *pvUser) 156 207 { … … 162 213 { "--help", 'h', RTGETOPT_REQ_NOTHING }, 163 214 { "--version", 'V', RTGETOPT_REQ_NOTHING }, 215 { "--llvm-input", 'l', RTGETOPT_REQ_STRING }, 216 { "--file", 'f', RTGETOPT_REQ_STRING }, 164 217 }; 165 218 … … 172 225 /* Option variables: */ 173 226 RTFUZZCMDCLIENT This; 174 175 This.pfnConsume = pfnConsume; 176 This.pvUser = pvUser; 227 RTLDRMOD hLlvmMod = NIL_RTLDRMOD; 228 const char *pszFilename = NULL; 229 230 This.pfnConsume = pfnConsume; 231 This.pvUser = pvUser; 232 This.enmInputChan = RTFUZZOBSINPUTCHAN_FUZZING_AWARE_CLIENT; 177 233 178 234 /* Argument parsing loop. */ 179 235 bool fContinue = true; 236 bool fExit = false; 180 237 do 181 238 { … … 188 245 break; 189 246 247 case 'f': 248 { 249 pszFilename = ValueUnion.psz; 250 This.enmInputChan = RTFUZZOBSINPUTCHAN_FILE; 251 break; 252 } 253 254 case 'l': 255 { 256 /* 257 * Load the indicated library and try to resolve LLVMFuzzerTestOneInput, 258 * which will act as the input callback. 259 */ 260 rc = RTLdrLoad(ValueUnion.psz, &hLlvmMod); 261 if (RT_SUCCESS(rc)) 262 { 263 rc = RTLdrGetSymbol(hLlvmMod, "LLVMFuzzerTestOneInput", (void **)&This.pfnLlvmFuzzerTestOneInput); 264 if (RT_FAILURE(rc)) 265 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to query '%s' from '%s': %Rrc", 266 "LLVMFuzzerTestOneInput", 267 ValueUnion.psz, 268 rc); 269 } 270 break; 271 } 272 190 273 case 'h': 191 274 RTPrintf("Usage: to be written\nOption dump:\n"); … … 193 276 RTPrintf(" -%c,%s\n", s_aOptions[i].iShort, s_aOptions[i].pszLong); 194 277 fContinue = false; 278 fExit = true; 195 279 break; 196 280 … … 198 282 RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); 199 283 fContinue = false; 284 fExit = true; 200 285 break; 201 286 … … 207 292 } while (fContinue); 208 293 209 if (rcExit == RTEXITCODE_SUCCESS) 210 rcExit = rtFuzzCmdClientRun(&This); 294 if ( rcExit == RTEXITCODE_SUCCESS 295 && !fExit) 296 { 297 switch (This.enmInputChan) 298 { 299 case RTFUZZOBSINPUTCHAN_FUZZING_AWARE_CLIENT: 300 rcExit = rtFuzzCmdClientRun(&This); 301 break; 302 case RTFUZZOBSINPUTCHAN_FILE: 303 rcExit = rtFuzzCmdClientRunFile(&This, pszFilename); 304 break; 305 default: 306 rcExit = RTMsgErrorExit(RTEXITCODE_SYNTAX, "Input channel unknown/not implemented yet"); 307 } 308 } 309 310 if (hLlvmMod != NIL_RTLDRMOD) 311 RTLdrClose(hLlvmMod); 211 312 } 212 313 else
Note:
See TracChangeset
for help on using the changeset viewer.