VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: tstDeviceSsmFuzz.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * tstDeviceSsmFuzz - SSM fuzzing testcase.
4 */
5
6/*
7 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DEFAULT /** @todo */
33#include <VBox/types.h>
34#include <iprt/errcore.h>
35#include <iprt/mem.h>
36#include <iprt/fuzz.h>
37#include <iprt/time.h>
38#include <iprt/string.h>
39
40#include "tstDeviceBuiltin.h"
41#include "tstDeviceCfg.h"
42#include "tstDeviceInternal.h"
43
44
45/*********************************************************************************************************************************
46* Defined Constants And Macros *
47*********************************************************************************************************************************/
48
49
50/*********************************************************************************************************************************
51* Structures and Typedefs *
52*********************************************************************************************************************************/
53
54
55static PCTSTDEVCFGITEM tstDevSsmFuzzGetCfgItem(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
56{
57 for (uint32_t i = 0; i < cCfgItems; i++)
58 {
59 if (!RTStrCmp(paCfg[i].pszKey, pszName))
60 return &paCfg[i];
61 }
62
63 return NULL;
64}
65
66
67static const char *tstDevSsmFuzzGetCfgString(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
68{
69 PCTSTDEVCFGITEM pCfgItem = tstDevSsmFuzzGetCfgItem(paCfg, cCfgItems, pszName);
70 if ( pCfgItem
71 && pCfgItem->enmType == TSTDEVCFGITEMTYPE_STRING)
72 return pCfgItem->u.psz;
73
74 return NULL;
75}
76
77
78static uint64_t tstDevSsmFuzzGetCfgU64(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
79{
80 PCTSTDEVCFGITEM pCfgItem = tstDevSsmFuzzGetCfgItem(paCfg, cCfgItems, pszName);
81 if ( pCfgItem
82 && pCfgItem->enmType == TSTDEVCFGITEMTYPE_INTEGER)
83 return (uint64_t)pCfgItem->u.i64;
84
85 return 0;
86}
87
88
89static uint32_t tstDevSsmFuzzGetCfgU32(PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems, const char *pszName)
90{
91 PCTSTDEVCFGITEM pCfgItem = tstDevSsmFuzzGetCfgItem(paCfg, cCfgItems, pszName);
92 if ( pCfgItem
93 && pCfgItem->enmType == TSTDEVCFGITEMTYPE_INTEGER)
94 return (uint32_t)pCfgItem->u.i64;
95
96 return 0;
97}
98
99
100/**
101 * Entry point for the SSM fuzzer.
102 *
103 * @returns VBox status code.
104 * @param hDut The device under test.
105 * @param paCfg The testcase config.
106 * @param cCfgItems Number of config items.
107 */
108static DECLCALLBACK(int) tstDevSsmFuzzEntry(TSTDEVDUT hDut, PCTSTDEVCFGITEM paCfg, uint32_t cCfgItems)
109{
110 RTFUZZCTX hFuzzCtx;
111 int rc = RTFuzzCtxCreate(&hFuzzCtx, RTFUZZCTXTYPE_BLOB);
112 if (RT_SUCCESS(rc))
113 {
114 RTFUZZCFG hFuzzCfg;
115 rc = RTFuzzCfgCreateFromFile(&hFuzzCfg, tstDevSsmFuzzGetCfgString(paCfg, cCfgItems, "CorpusPath"), NULL);
116 if (RT_SUCCESS(rc))
117 {
118 rc = RTFuzzCfgImport(hFuzzCfg, hFuzzCtx, RTFUZZCFG_IMPORT_F_DEFAULT);
119 RTFuzzCfgRelease(hFuzzCfg);
120 }
121
122 if (RT_SUCCESS(rc))
123 {
124 /* Create a new SSM handle to use. */
125 PSSMHANDLE pSsm = (PSSMHANDLE)RTMemAllocZ(sizeof(*pSsm));
126 if (RT_LIKELY(pSsm))
127 {
128 pSsm->pDut = hDut;
129 pSsm->pbSavedState = NULL;
130 pSsm->cbSavedState = 0;
131 pSsm->offDataBuffer = 0;
132 pSsm->uCurUnitVer = tstDevSsmFuzzGetCfgU32(paCfg, cCfgItems, "UnitVersion");
133 pSsm->rc = VINF_SUCCESS;
134
135 uint64_t cRuntimeMs = tstDevSsmFuzzGetCfgU64(paCfg, cCfgItems, "RuntimeSec") * RT_MS_1SEC_64;
136 uint64_t tsStart = RTTimeMilliTS();
137 uint64_t cFuzzedInputs = 0;
138 do
139 {
140 RTFUZZINPUT hFuzzInp;
141 rc = RTFuzzCtxInputGenerate(hFuzzCtx, &hFuzzInp);
142 if (RT_SUCCESS(rc))
143 {
144 void *pvBlob = NULL;
145 size_t cbBlob = 0;
146
147 rc = RTFuzzInputQueryBlobData(hFuzzInp, &pvBlob, &cbBlob);
148 if (RT_SUCCESS(rc))
149 {
150 pSsm->pbSavedState = (uint8_t *)pvBlob;
151 pSsm->cbSavedState = cbBlob;
152 pSsm->offDataBuffer = 0;
153 pSsm->rc = VINF_SUCCESS;
154
155 /* Get the SSM handler from the device. */
156 int rcDut = VINF_SUCCESS;
157 PTSTDEVDUTSSM pSsmClbks = RTListGetFirst(&hDut->LstSsmHandlers, TSTDEVDUTSSM, NdSsm);
158 if (pSsmClbks)
159 {
160 /* Load preparations. */
161 if (pSsmClbks->pfnLoadPrep)
162 rcDut = pSsmClbks->pfnLoadPrep(hDut->pDevIns, pSsm);
163 if (RT_SUCCESS(rcDut))
164 rcDut = pSsmClbks->pfnLoadExec(hDut->pDevIns, pSsm, pSsm->uCurUnitVer, SSM_PASS_FINAL);
165
166 cFuzzedInputs++;
167 }
168 if (RT_SUCCESS(rcDut))
169 RTFuzzInputAddToCtxCorpus(hFuzzInp);
170 }
171 RTFuzzInputRelease(hFuzzInp);
172 }
173 } while ( RT_SUCCESS(rc)
174 && RTTimeMilliTS() - tsStart < cRuntimeMs);
175
176 RTMemFree(pSsm);
177 }
178 else
179 rc = VERR_NO_MEMORY;
180 }
181
182 RTFuzzCtxRelease(hFuzzCtx);
183 }
184
185 return rc;
186}
187
188
189const TSTDEVTESTCASEREG g_TestcaseSsmFuzz =
190{
191 /** szName */
192 "SsmFuzz",
193 /** pszDesc */
194 "Fuzzes devices SSM state loaders",
195 /** fFlags */
196 0,
197 /** pfnTestEntry */
198 tstDevSsmFuzzEntry
199};
200
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use