VirtualBox

source: vbox/trunk/src/VBox/Devices/testcase/tstDeviceSsmFuzz.cpp@ 83296

Last change on this file since 83296 was 83296, checked in by vboxsync, 5 years ago

Devices/tstDevice: Copy over and modify PDMThread* API so we can fuzz saved states of device s which delegate some parts of the saved state loading to workers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: tstDeviceSsmFuzz.cpp 83296 2020-03-16 11:43:32Z vboxsync $ */
2/** @file
3 * tstDeviceSsmFuzz - SSM fuzzing testcase.
4 */
5
6/*
7 * Copyright (C) 2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEFAULT /** @todo */
23#include <VBox/types.h>
24#include <iprt/errcore.h>
25#include <iprt/mem.h>
26#include <iprt/fuzz.h>
27#include <iprt/time.h>
28#include <iprt/string.h>
29
30#include "tstDeviceBuiltin.h"
31#include "tstDeviceCfg.h"
32#include "tstDeviceInternal.h"
33
34
35/*********************************************************************************************************************************
36* Defined Constants And Macros *
37*********************************************************************************************************************************/
38
39
40/*********************************************************************************************************************************
41* Structures and Typedefs *
42*********************************************************************************************************************************/
43
44
45static PCTSTDEVCFGITEM tstDevSsmFuzzGetCfgItem(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
46{
47 for (uint32_t i = 0; i < cCfgItems; i++)
48 {
49 if (!RTStrCmp(paCfg[i].pszKey, pszName))
50 return &paCfg[i];
51 }
52
53 return NULL;
54}
55
56
57static const char *tstDevSsmFuzzGetCfgString(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
58{
59 PCTSTDEVCFGITEM pCfgItem = tstDevSsmFuzzGetCfgItem(paCfg, cCfgItems, pszName);
60 if ( pCfgItem
61 && pCfgItem->enmType == TSTDEVCFGITEMTYPE_STRING)
62 return pCfgItem->u.psz;
63
64 return NULL;
65}
66
67
68static uint64_t tstDevSsmFuzzGetCfgU64(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
69{
70 PCTSTDEVCFGITEM pCfgItem = tstDevSsmFuzzGetCfgItem(paCfg, cCfgItems, pszName);
71 if ( pCfgItem
72 && pCfgItem->enmType == TSTDEVCFGITEMTYPE_INTEGER)
73 return (uint64_t)pCfgItem->u.i64;
74
75 return 0;
76}
77
78
79static uint32_t tstDevSsmFuzzGetCfgU32(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
80{
81 PCTSTDEVCFGITEM pCfgItem = tstDevSsmFuzzGetCfgItem(paCfg, cCfgItems, pszName);
82 if ( pCfgItem
83 && pCfgItem->enmType == TSTDEVCFGITEMTYPE_INTEGER)
84 return (uint32_t)pCfgItem->u.i64;
85
86 return 0;
87}
88
89
90/**
91 * Entry point for the SSM fuzzer.
92 *
93 * @returns VBox status code.
94 * @param hDut The device under test.
95 * @param paCfg The testcase config.
96 * @param cCfgItems Number of config items.
97 */
98static DECLCALLBACK(int) tstDevSsmFuzzEntry(TSTDEVDUT hDut, PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems)
99{
100 RT_NOREF(hDut, paCfg);
101
102 RTFUZZCTX hFuzzCtx;
103 int rc = RTFuzzCtxCreate(&hFuzzCtx, RTFUZZCTXTYPE_BLOB);
104 if (RT_SUCCESS(rc))
105 {
106 uint64_t cbMutateRange = tstDevSsmFuzzGetCfgU64(paCfg, cCfgItems, "OffMutateSize");
107 if (!cbMutateRange)
108 cbMutateRange = UINT64_MAX;
109
110 rc = RTFuzzCtxCfgSetMutationRange(hFuzzCtx,
111 tstDevSsmFuzzGetCfgU64(paCfg, cCfgItems, "OffMutateStart"),
112 cbMutateRange);
113 if (RT_SUCCESS(rc))
114 rc = RTFuzzCtxCorpusInputAddFromDirPath(hFuzzCtx, tstDevSsmFuzzGetCfgString(paCfg, cCfgItems, "CorpusPath"));
115 if (RT_SUCCESS(rc))
116 {
117 rc = RTFuzzCtxCfgSetInputSeedMaximum(hFuzzCtx, (size_t)tstDevSsmFuzzGetCfgU64(paCfg, cCfgItems, "InputSizeMax"));
118 if (RT_SUCCESS(rc))
119 {
120 rc = RTFuzzCtxReseed(hFuzzCtx, tstDevSsmFuzzGetCfgU64(paCfg, cCfgItems, "Seed"));
121 if (RT_SUCCESS(rc))
122 {
123 /* Create a new SSM handle to use. */
124 PSSMHANDLE pSsm = (PSSMHANDLE)RTMemAllocZ(sizeof(*pSsm));
125 if (RT_LIKELY(pSsm))
126 {
127 pSsm->pDut = hDut;
128 pSsm->pbSavedState = NULL;
129 pSsm->cbSavedState = 0;
130 pSsm->offDataBuffer = 0;
131 pSsm->uCurUnitVer = tstDevSsmFuzzGetCfgU32(paCfg, cCfgItems, "UnitVersion");
132 pSsm->rc = VINF_SUCCESS;
133
134 uint64_t cRuntimeMs = tstDevSsmFuzzGetCfgU64(paCfg, cCfgItems, "RuntimeSec") * RT_MS_1SEC_64;
135 uint64_t tsStart = RTTimeMilliTS();
136 uint64_t cFuzzedInputs = 0;
137 do
138 {
139 RTFUZZINPUT hFuzzInp;
140 rc = RTFuzzCtxInputGenerate(hFuzzCtx, &hFuzzInp);
141 if (RT_SUCCESS(rc))
142 {
143 void *pvBlob = NULL;
144 size_t cbBlob = 0;
145
146 rc = RTFuzzInputQueryBlobData(hFuzzInp, &pvBlob, &cbBlob);
147 if (RT_SUCCESS(rc))
148 {
149 pSsm->pbSavedState = (uint8_t *)pvBlob;
150 pSsm->cbSavedState = cbBlob;
151 pSsm->offDataBuffer = 0;
152 pSsm->rc = VINF_SUCCESS;
153
154 /* Get the SSM handler from the device. */
155 int rcDut = VINF_SUCCESS;
156 PTSTDEVDUTSSM pSsmClbks = RTListGetFirst(&hDut->LstSsmHandlers, TSTDEVDUTSSM, NdSsm);
157 if (pSsmClbks)
158 {
159 /* Load preparations. */
160 if (pSsmClbks->pfnLoadPrep)
161 rcDut = pSsmClbks->pfnLoadPrep(hDut->pDevIns, pSsm);
162 if (RT_SUCCESS(rcDut))
163 rcDut = pSsmClbks->pfnLoadExec(hDut->pDevIns, pSsm, pSsm->uCurUnitVer, SSM_PASS_FINAL);
164
165 cFuzzedInputs++;
166 }
167 if (RT_SUCCESS(rcDut))
168 RTFuzzInputAddToCtxCorpus(hFuzzInp);
169 }
170 RTFuzzInputRelease(hFuzzInp);
171 }
172 } while ( RT_SUCCESS(rc)
173 && RTTimeMilliTS() - tsStart < cRuntimeMs);
174
175 RTMemFree(pSsm);
176 }
177 else
178 rc = VERR_NO_MEMORY;
179 }
180 }
181 }
182
183 RTFuzzCtxRelease(hFuzzCtx);
184 }
185
186 return rc;
187}
188
189
190const TSTDEVTESTCASEREG g_TestcaseSsmFuzz =
191{
192 /** szName */
193 "SsmFuzz",
194 /** pszDesc */
195 "Fuzzes devices SSM state loaders",
196 /** fFlags */
197 0,
198 /** pfnTestEntry */
199 tstDevSsmFuzzEntry
200};
201
Note: See TracBrowser for help on using the repository browser.

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