Changeset 77564 in vbox for trunk/src/VBox/Runtime/common/fuzz/fuzzclientcmd.cpp
- Timestamp:
- Mar 5, 2019 10:30:33 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.