VirtualBox

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

Last change on this file since 91998 was 91998, checked in by vboxsync, 3 years ago

Devices/testcase: Some fun with the device fuzzing framework, bugref:9006

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: tstDeviceSsmFuzz.cpp 91998 2021-10-22 08:58:44Z 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.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
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 RTFUZZCTX hFuzzCtx;
101 int rc = RTFuzzCtxCreate(&hFuzzCtx, RTFUZZCTXTYPE_BLOB);
102 if (RT_SUCCESS(rc))
103 {
104 RTFUZZCFG hFuzzCfg;
105 rc = RTFuzzCfgCreateFromFile(&hFuzzCfg, tstDevSsmFuzzGetCfgString(paCfg, cCfgItems, "CorpusPath"), NULL);
106 if (RT_SUCCESS(rc))
107 {
108 rc = RTFuzzCfgImport(hFuzzCfg, hFuzzCtx, RTFUZZCFG_IMPORT_F_DEFAULT);
109 RTFuzzCfgRelease(hFuzzCfg);
110 }
111
112 if (RT_SUCCESS(rc))
113 {
114 /* Create a new SSM handle to use. */
115 PSSMHANDLE pSsm = (PSSMHANDLE)RTMemAllocZ(sizeof(*pSsm));
116 if (RT_LIKELY(pSsm))
117 {
118 pSsm->pDut = hDut;
119 pSsm->pbSavedState = NULL;
120 pSsm->cbSavedState = 0;
121 pSsm->offDataBuffer = 0;
122 pSsm->uCurUnitVer = tstDevSsmFuzzGetCfgU32(paCfg, cCfgItems, "UnitVersion");
123 pSsm->rc = VINF_SUCCESS;
124
125 uint64_t cRuntimeMs = tstDevSsmFuzzGetCfgU64(paCfg, cCfgItems, "RuntimeSec") * RT_MS_1SEC_64;
126 uint64_t tsStart = RTTimeMilliTS();
127 uint64_t cFuzzedInputs = 0;
128 do
129 {
130 RTFUZZINPUT hFuzzInp;
131 rc = RTFuzzCtxInputGenerate(hFuzzCtx, &hFuzzInp);
132 if (RT_SUCCESS(rc))
133 {
134 void *pvBlob = NULL;
135 size_t cbBlob = 0;
136
137 rc = RTFuzzInputQueryBlobData(hFuzzInp, &pvBlob, &cbBlob);
138 if (RT_SUCCESS(rc))
139 {
140 pSsm->pbSavedState = (uint8_t *)pvBlob;
141 pSsm->cbSavedState = cbBlob;
142 pSsm->offDataBuffer = 0;
143 pSsm->rc = VINF_SUCCESS;
144
145 /* Get the SSM handler from the device. */
146 int rcDut = VINF_SUCCESS;
147 PTSTDEVDUTSSM pSsmClbks = RTListGetFirst(&hDut->LstSsmHandlers, TSTDEVDUTSSM, NdSsm);
148 if (pSsmClbks)
149 {
150 /* Load preparations. */
151 if (pSsmClbks->pfnLoadPrep)
152 rcDut = pSsmClbks->pfnLoadPrep(hDut->pDevIns, pSsm);
153 if (RT_SUCCESS(rcDut))
154 rcDut = pSsmClbks->pfnLoadExec(hDut->pDevIns, pSsm, pSsm->uCurUnitVer, SSM_PASS_FINAL);
155
156 cFuzzedInputs++;
157 }
158 if (RT_SUCCESS(rcDut))
159 RTFuzzInputAddToCtxCorpus(hFuzzInp);
160 }
161 RTFuzzInputRelease(hFuzzInp);
162 }
163 } while ( RT_SUCCESS(rc)
164 && RTTimeMilliTS() - tsStart < cRuntimeMs);
165
166 RTMemFree(pSsm);
167 }
168 else
169 rc = VERR_NO_MEMORY;
170 }
171
172 RTFuzzCtxRelease(hFuzzCtx);
173 }
174
175 return rc;
176}
177
178
179const TSTDEVTESTCASEREG g_TestcaseSsmFuzz =
180{
181 /** szName */
182 "SsmFuzz",
183 /** pszDesc */
184 "Fuzzes devices SSM state loaders",
185 /** fFlags */
186 0,
187 /** pfnTestEntry */
188 tstDevSsmFuzzEntry
189};
190
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