VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/fuzz/fuzzclientcmd.cpp@ 76707

Last change on this file since 76707 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: fuzzclientcmd.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT - Fuzzing framework API, fuzzed client command.
4 */
5
6/*
7 * Copyright (C) 2018-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/fuzz.h>
32#include "internal/iprt.h"
33
34#include <iprt/assert.h>
35#include <iprt/buildconfig.h>
36#include <iprt/errcore.h>
37#include <iprt/getopt.h>
38#include <iprt/mem.h>
39#include <iprt/message.h>
40#include <iprt/stream.h>
41#include <iprt/string.h>
42#include <iprt/types.h>
43#include <iprt/vfs.h>
44
45
46/**
47 * Fuzzing client command state.
48 */
49typedef struct RTFUZZCMDCLIENT
50{
51 /** Our own fuzzing context containing all the data. */
52 RTFUZZCTX hFuzzCtx;
53 /** Consumption callback. */
54 PFNFUZZCLIENTCONSUME pfnConsume;
55 /** Opaque user data to pass to the consumption callback. */
56 void *pvUser;
57 /** Standard input VFS handle. */
58 RTVFSIOSTREAM hVfsStdIn;
59 /** Standard output VFS handle. */
60 RTVFSIOSTREAM hVfsStdOut;
61} RTFUZZCMDCLIENT;
62/** Pointer to a fuzzing client command state. */
63typedef RTFUZZCMDCLIENT *PRTFUZZCMDCLIENT;
64
65
66/**
67 * The fuzzing client mainloop.
68 *
69 * @returns IPRT status code.
70 * @param pThis The fuzzing client command state.
71 */
72static int rtFuzzCmdClientMainloop(PRTFUZZCMDCLIENT pThis)
73{
74 int rc = VINF_SUCCESS;
75 bool fShutdown = false;
76
77 while ( !fShutdown
78 && RT_SUCCESS(rc))
79 {
80 RTFUZZINPUT hFuzzInput;
81
82 rc = RTFuzzCtxInputGenerate(pThis->hFuzzCtx, &hFuzzInput);
83 if (RT_SUCCESS(rc))
84 {
85 void *pv = NULL;
86 size_t cb = 0;
87 rc = RTFuzzInputQueryData(hFuzzInput, &pv, &cb);
88 if (RT_SUCCESS(rc))
89 {
90 char bResp = '.';
91 int rc2 = pThis->pfnConsume(pv, cb, pThis->pvUser);
92 if (RT_SUCCESS(rc2))
93 {
94 rc = RTFuzzInputAddToCtxCorpus(hFuzzInput);
95 bResp = 'A';
96 }
97
98 if (RT_SUCCESS(rc))
99 rc = RTVfsIoStrmWrite(pThis->hVfsStdOut, &bResp, 1, true /*fBlocking*/, NULL);
100 }
101
102 RTFuzzInputRelease(hFuzzInput);
103 }
104 }
105
106 return rc;
107}
108
109
110/**
111 * Run the fuzzing client.
112 *
113 * @returns Process exit status.
114 * @param pThis The fuzzing client command state.
115 */
116static RTEXITCODE rtFuzzCmdClientRun(PRTFUZZCMDCLIENT pThis)
117{
118 int rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_INPUT, 0, true /*fLeaveOpen*/, &pThis->hVfsStdIn);
119 if (RT_SUCCESS(rc))
120 {
121 rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, 0, true /*fLeaveOpen*/, &pThis->hVfsStdOut);
122 if (RT_SUCCESS(rc))
123 {
124 /* Read the initial input fuzzer state from the standard input. */
125 uint32_t cbFuzzCtxState;
126 rc = RTVfsIoStrmRead(pThis->hVfsStdIn, &cbFuzzCtxState, sizeof(cbFuzzCtxState), true /*fBlocking*/, NULL);
127 if (RT_SUCCESS(rc))
128 {
129 void *pvFuzzCtxState = RTMemAllocZ(cbFuzzCtxState);
130 if (RT_LIKELY(pvFuzzCtxState))
131 {
132 rc = RTVfsIoStrmRead(pThis->hVfsStdIn, pvFuzzCtxState, cbFuzzCtxState, true /*fBlocking*/, NULL);
133 if (RT_SUCCESS(rc))
134 {
135 rc = RTFuzzCtxCreateFromState(&pThis->hFuzzCtx, pvFuzzCtxState, cbFuzzCtxState);
136 if (RT_SUCCESS(rc))
137 rc = rtFuzzCmdClientMainloop(pThis);
138 }
139
140 RTMemFree(pvFuzzCtxState);
141 }
142 else
143 rc = VERR_NO_MEMORY;
144 }
145 }
146 }
147
148 if (RT_SUCCESS(rc))
149 return RTEXITCODE_SUCCESS;
150
151 return RTEXITCODE_FAILURE;
152}
153
154
155RTR3DECL(RTEXITCODE) RTFuzzCmdFuzzingClient(unsigned cArgs, char **papszArgs, PFNFUZZCLIENTCONSUME pfnConsume, void *pvUser)
156{
157 /*
158 * Parse the command line.
159 */
160 static const RTGETOPTDEF s_aOptions[] =
161 {
162 { "--help", 'h', RTGETOPT_REQ_NOTHING },
163 { "--version", 'V', RTGETOPT_REQ_NOTHING },
164 };
165
166 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
167 RTGETOPTSTATE GetState;
168 int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1,
169 RTGETOPTINIT_FLAGS_OPTS_FIRST);
170 if (RT_SUCCESS(rc))
171 {
172 /* Option variables: */
173 RTFUZZCMDCLIENT This;
174
175 This.pfnConsume = pfnConsume;
176 This.pvUser = pvUser;
177
178 /* Argument parsing loop. */
179 bool fContinue = true;
180 do
181 {
182 RTGETOPTUNION ValueUnion;
183 int chOpt = RTGetOpt(&GetState, &ValueUnion);
184 switch (chOpt)
185 {
186 case 0:
187 fContinue = false;
188 break;
189
190 case 'h':
191 RTPrintf("Usage: to be written\nOption dump:\n");
192 for (unsigned i = 0; i < RT_ELEMENTS(s_aOptions); i++)
193 RTPrintf(" -%c,%s\n", s_aOptions[i].iShort, s_aOptions[i].pszLong);
194 fContinue = false;
195 break;
196
197 case 'V':
198 RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision());
199 fContinue = false;
200 break;
201
202 default:
203 rcExit = RTGetOptPrintError(chOpt, &ValueUnion);
204 fContinue = false;
205 break;
206 }
207 } while (fContinue);
208
209 if (rcExit == RTEXITCODE_SUCCESS)
210 rcExit = rtFuzzCmdClientRun(&This);
211 }
212 else
213 rcExit = RTMsgErrorExit(RTEXITCODE_SYNTAX, "RTGetOptInit: %Rrc", rc);
214 return rcExit;
215}
216
Note: See TracBrowser for help on using the repository browser.

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