Skip to content

Commit e314ba4

Browse files
test: add internal plugin harnesses
1 parent 8c8c87e commit e314ba4

9 files changed

Lines changed: 1179 additions & 0 deletions
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include "fuzz_utils.h"
2+
#include "cmd_get_gating.h"
3+
4+
int fuzzGating(const uint8_t *data, size_t size) {
5+
size_t offset = 0;
6+
size_t len = 0;
7+
uint8_t p1;
8+
uint8_t p2;
9+
10+
while (size - offset > 4) {
11+
if (data[offset++] == 0) break;
12+
p1 = data[offset++];
13+
p2 = data[offset++];
14+
len = data[offset++];
15+
if (size - offset < len) return 0;
16+
if (handle_gating(p1, p2, data + offset, len) != SWO_SUCCESS) return 0;
17+
offset += len;
18+
}
19+
set_gating_warning();
20+
return 0;
21+
}
22+
23+
/* Main fuzzing handler called by libfuzzer */
24+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
25+
init_fuzzing_environment();
26+
27+
fuzzGating(data, size);
28+
29+
return 0;
30+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/**
2+
* Fuzzing harness for the EIP-7002 internal plugin (withdrawal requests)
3+
*/
4+
5+
#include "fuzz_utils.h"
6+
#include "eip7002_plugin.h"
7+
8+
// Buffer sizes for UI queries
9+
#define NAME_LENGTH 32
10+
#define VERSION_LENGTH 32
11+
#define TITLE_LENGTH 32
12+
#define MSG_LENGTH 79
13+
14+
static int fuzz_eip7002_plugin(const uint8_t *data, size_t size) {
15+
ethPluginInitContract_t init_contract = {0};
16+
ethPluginProvideParameter_t provide_param = {0};
17+
ethPluginFinalize_t finalize = {0};
18+
ethPluginProvideInfo_t provide_info = {0};
19+
ethQueryContractID_t query_id = {0};
20+
ethQueryContractUI_t query_ui = {0};
21+
txContent_t content = {0};
22+
23+
uint8_t plugin_context[PLUGIN_CONTEXT_SIZE] = {0};
24+
25+
const uint8_t address[ADDRESS_LENGTH] = {0};
26+
27+
char name[NAME_LENGTH] = {0};
28+
char version[VERSION_LENGTH] = {0};
29+
char title[TITLE_LENGTH] = {0};
30+
char msg[MSG_LENGTH] = {0};
31+
32+
extraInfo_t item1 = {0};
33+
extraInfo_t item2 = {0};
34+
35+
// Need at least selector (4 bytes)
36+
if (size < SELECTOR_SIZE) {
37+
return 0;
38+
}
39+
40+
// Initialize content from fuzzed data if available
41+
if (size >= SELECTOR_SIZE + sizeof(txContent_t)) {
42+
memcpy(&content, data + SELECTOR_SIZE, sizeof(txContent_t));
43+
}
44+
45+
// Setup init contract
46+
init_contract.interfaceVersion = ETH_PLUGIN_INTERFACE_VERSION_LATEST;
47+
init_contract.selector = data;
48+
init_contract.txContent = &content;
49+
init_contract.pluginContext = plugin_context;
50+
init_contract.pluginContextLength = sizeof(plugin_context);
51+
init_contract.dataSize = size;
52+
53+
eip7002_plugin_call(ETH_PLUGIN_INIT_CONTRACT, &init_contract);
54+
if (init_contract.result != ETH_PLUGIN_RESULT_OK) {
55+
return 0;
56+
}
57+
58+
// Provide parameters
59+
size_t offset = SELECTOR_SIZE;
60+
if (size >= SELECTOR_SIZE + sizeof(txContent_t)) {
61+
offset += sizeof(txContent_t);
62+
}
63+
64+
while (size - offset >= PARAMETER_LENGTH) {
65+
provide_param.parameter = data + offset;
66+
provide_param.parameterOffset = offset;
67+
provide_param.parameter_size = PARAMETER_LENGTH;
68+
provide_param.pluginContext = plugin_context;
69+
provide_param.txContent = &content;
70+
71+
eip7002_plugin_call(ETH_PLUGIN_PROVIDE_PARAMETER, &provide_param);
72+
if (provide_param.result != ETH_PLUGIN_RESULT_OK) {
73+
return 0;
74+
}
75+
offset += PARAMETER_LENGTH;
76+
}
77+
78+
// Handle remaining bytes if any (last parameter may be smaller)
79+
if (size - offset > 0) {
80+
provide_param.parameter = data + offset;
81+
provide_param.parameterOffset = offset;
82+
provide_param.parameter_size = size - offset;
83+
provide_param.pluginContext = plugin_context;
84+
provide_param.txContent = &content;
85+
86+
eip7002_plugin_call(ETH_PLUGIN_PROVIDE_PARAMETER, &provide_param);
87+
if (provide_param.result != ETH_PLUGIN_RESULT_OK) {
88+
return 0;
89+
}
90+
}
91+
92+
// Finalize
93+
finalize.pluginContext = plugin_context;
94+
finalize.address = address;
95+
finalize.txContent = &content;
96+
97+
eip7002_plugin_call(ETH_PLUGIN_FINALIZE, &finalize);
98+
if (finalize.result != ETH_PLUGIN_RESULT_OK) {
99+
return 0;
100+
}
101+
102+
// Provide token info if requested
103+
if (finalize.tokenLookup1 || finalize.tokenLookup2) {
104+
provide_info.pluginContext = plugin_context;
105+
provide_info.txContent = &content;
106+
if (finalize.tokenLookup1) {
107+
provide_info.item1 = &item1;
108+
}
109+
if (finalize.tokenLookup2) {
110+
provide_info.item2 = &item2;
111+
}
112+
113+
eip7002_plugin_call(ETH_PLUGIN_PROVIDE_INFO, &provide_info);
114+
if (provide_info.result != ETH_PLUGIN_RESULT_OK &&
115+
provide_info.result != ETH_PLUGIN_RESULT_FALLBACK) {
116+
return 0;
117+
}
118+
}
119+
120+
// Query contract ID
121+
query_id.pluginContext = plugin_context;
122+
query_id.txContent = &content;
123+
query_id.name = name;
124+
query_id.nameLength = sizeof(name);
125+
query_id.version = version;
126+
query_id.versionLength = sizeof(version);
127+
128+
eip7002_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_ID, &query_id);
129+
if (query_id.result != ETH_PLUGIN_RESULT_OK) {
130+
return 0;
131+
}
132+
133+
// Query contract UI for each screen
134+
uint8_t total_screens = finalize.numScreens + provide_info.additionalScreens;
135+
for (uint8_t i = 0; i < total_screens; i++) {
136+
query_ui.pluginContext = plugin_context;
137+
query_ui.txContent = &content;
138+
query_ui.title = title;
139+
query_ui.titleLength = sizeof(title);
140+
query_ui.msg = msg;
141+
query_ui.msgLength = sizeof(msg);
142+
query_ui.screenIndex = i;
143+
144+
eip7002_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_UI, &query_ui);
145+
if (query_ui.result != ETH_PLUGIN_RESULT_OK) {
146+
return 0;
147+
}
148+
}
149+
150+
return 0;
151+
}
152+
153+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
154+
init_fuzzing_environment();
155+
fuzz_eip7002_plugin(data, size);
156+
return 0;
157+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/**
2+
* Fuzzing harness for the EIP-7251 internal plugin (consolidation requests)
3+
*/
4+
5+
#include "fuzz_utils.h"
6+
#include "eip7251_plugin.h"
7+
8+
// Buffer sizes for UI queries
9+
#define NAME_LENGTH 32
10+
#define VERSION_LENGTH 32
11+
#define TITLE_LENGTH 32
12+
#define MSG_LENGTH 79
13+
14+
static int fuzz_eip7251_plugin(const uint8_t *data, size_t size) {
15+
ethPluginInitContract_t init_contract = {0};
16+
ethPluginProvideParameter_t provide_param = {0};
17+
ethPluginFinalize_t finalize = {0};
18+
ethPluginProvideInfo_t provide_info = {0};
19+
ethQueryContractID_t query_id = {0};
20+
ethQueryContractUI_t query_ui = {0};
21+
txContent_t content = {0};
22+
23+
uint8_t plugin_context[PLUGIN_CONTEXT_SIZE] = {0};
24+
25+
const uint8_t address[ADDRESS_LENGTH] = {0};
26+
27+
char name[NAME_LENGTH] = {0};
28+
char version[VERSION_LENGTH] = {0};
29+
char title[TITLE_LENGTH] = {0};
30+
char msg[MSG_LENGTH] = {0};
31+
32+
extraInfo_t item1 = {0};
33+
extraInfo_t item2 = {0};
34+
35+
// Need at least selector (4 bytes)
36+
if (size < SELECTOR_SIZE) {
37+
return 0;
38+
}
39+
40+
// Initialize content from fuzzed data if available
41+
if (size >= SELECTOR_SIZE + sizeof(txContent_t)) {
42+
memcpy(&content, data + SELECTOR_SIZE, sizeof(txContent_t));
43+
}
44+
45+
// Setup init contract
46+
init_contract.interfaceVersion = ETH_PLUGIN_INTERFACE_VERSION_LATEST;
47+
init_contract.selector = data;
48+
init_contract.txContent = &content;
49+
init_contract.pluginContext = plugin_context;
50+
init_contract.pluginContextLength = sizeof(plugin_context);
51+
init_contract.dataSize = size;
52+
53+
eip7251_plugin_call(ETH_PLUGIN_INIT_CONTRACT, &init_contract);
54+
if (init_contract.result != ETH_PLUGIN_RESULT_OK) {
55+
return 0;
56+
}
57+
58+
// Provide parameters
59+
size_t offset = SELECTOR_SIZE;
60+
if (size >= SELECTOR_SIZE + sizeof(txContent_t)) {
61+
offset += sizeof(txContent_t);
62+
}
63+
64+
while (size - offset >= PARAMETER_LENGTH) {
65+
provide_param.parameter = data + offset;
66+
provide_param.parameterOffset = offset;
67+
provide_param.parameter_size = PARAMETER_LENGTH;
68+
provide_param.pluginContext = plugin_context;
69+
provide_param.txContent = &content;
70+
71+
eip7251_plugin_call(ETH_PLUGIN_PROVIDE_PARAMETER, &provide_param);
72+
if (provide_param.result != ETH_PLUGIN_RESULT_OK) {
73+
return 0;
74+
}
75+
offset += PARAMETER_LENGTH;
76+
}
77+
78+
// Handle remaining bytes if any (last parameter may be smaller)
79+
if (size - offset > 0) {
80+
provide_param.parameter = data + offset;
81+
provide_param.parameterOffset = offset;
82+
provide_param.parameter_size = size - offset;
83+
provide_param.pluginContext = plugin_context;
84+
provide_param.txContent = &content;
85+
86+
eip7251_plugin_call(ETH_PLUGIN_PROVIDE_PARAMETER, &provide_param);
87+
if (provide_param.result != ETH_PLUGIN_RESULT_OK) {
88+
return 0;
89+
}
90+
}
91+
92+
// Finalize
93+
finalize.pluginContext = plugin_context;
94+
finalize.address = address;
95+
finalize.txContent = &content;
96+
97+
eip7251_plugin_call(ETH_PLUGIN_FINALIZE, &finalize);
98+
if (finalize.result != ETH_PLUGIN_RESULT_OK) {
99+
return 0;
100+
}
101+
102+
// Provide token info if requested
103+
if (finalize.tokenLookup1 || finalize.tokenLookup2) {
104+
provide_info.pluginContext = plugin_context;
105+
provide_info.txContent = &content;
106+
if (finalize.tokenLookup1) {
107+
provide_info.item1 = &item1;
108+
}
109+
if (finalize.tokenLookup2) {
110+
provide_info.item2 = &item2;
111+
}
112+
113+
eip7251_plugin_call(ETH_PLUGIN_PROVIDE_INFO, &provide_info);
114+
if (provide_info.result != ETH_PLUGIN_RESULT_OK &&
115+
provide_info.result != ETH_PLUGIN_RESULT_FALLBACK) {
116+
return 0;
117+
}
118+
}
119+
120+
// Query contract ID
121+
query_id.pluginContext = plugin_context;
122+
query_id.txContent = &content;
123+
query_id.name = name;
124+
query_id.nameLength = sizeof(name);
125+
query_id.version = version;
126+
query_id.versionLength = sizeof(version);
127+
128+
eip7251_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_ID, &query_id);
129+
if (query_id.result != ETH_PLUGIN_RESULT_OK) {
130+
return 0;
131+
}
132+
133+
// Query contract UI for each screen
134+
uint8_t total_screens = finalize.numScreens + provide_info.additionalScreens;
135+
for (uint8_t i = 0; i < total_screens; i++) {
136+
query_ui.pluginContext = plugin_context;
137+
query_ui.txContent = &content;
138+
query_ui.title = title;
139+
query_ui.titleLength = sizeof(title);
140+
query_ui.msg = msg;
141+
query_ui.msgLength = sizeof(msg);
142+
query_ui.screenIndex = i;
143+
144+
eip7251_plugin_call(ETH_PLUGIN_QUERY_CONTRACT_UI, &query_ui);
145+
if (query_ui.result != ETH_PLUGIN_RESULT_OK) {
146+
return 0;
147+
}
148+
}
149+
150+
return 0;
151+
}
152+
153+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
154+
init_fuzzing_environment();
155+
fuzz_eip7251_plugin(data, size);
156+
return 0;
157+
}

0 commit comments

Comments
 (0)