p2p/
fuzzer.rs

1use openmina_fuzzer::{FuzzerState, MutationStrategy};
2use rand::Rng;
3
4use crate::{Data, YamuxFlags};
5
6pub fn mutate_pnet(fuzzer: &mut FuzzerState, data: &mut Vec<u8>) {
7    if fuzzer.gen_ratio(fuzzer.conf.pnet_mutation_rate) {
8        let mutation_strategy: MutationStrategy = if !data.is_empty() {
9            fuzzer.rng.gen_range(MutationStrategy::range()).into()
10        } else {
11            MutationStrategy::ExtendRandom
12        };
13
14        println!(
15            "[i] Mutating PNET data of len {} with strategy {:?}",
16            data.len(),
17            mutation_strategy
18        );
19
20        match mutation_strategy {
21            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.as_mut_slice()),
22            MutationStrategy::ExtendRandom => {
23                *data = fuzzer.extend_random(data.as_slice());
24            }
25            MutationStrategy::ExtendCopy => {
26                *data = fuzzer.extend_copy(data.as_slice());
27            }
28            MutationStrategy::Shrink => {
29                *data = fuzzer.shrink(data.as_slice());
30            }
31        }
32    }
33}
34
35pub fn mutate_noise(fuzzer: &mut FuzzerState, data: &mut Data) {
36    if fuzzer.gen_ratio(fuzzer.conf.noise_mutation_rate) {
37        let mutation_strategy: MutationStrategy = if !data.is_empty() {
38            fuzzer.rng.gen_range(MutationStrategy::range()).into()
39        } else {
40            MutationStrategy::ExtendRandom
41        };
42
43        println!(
44            "[i] Mutating Noise data of len {} with strategy {:?}",
45            data.len(),
46            mutation_strategy
47        );
48
49        match mutation_strategy {
50            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
51            MutationStrategy::ExtendRandom => {
52                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
53            }
54            MutationStrategy::ExtendCopy => {
55                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
56            }
57            MutationStrategy::Shrink => {
58                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
59            }
60        }
61    }
62}
63
64pub fn mutate_select_authentication(fuzzer: &mut FuzzerState, data: &mut Data) {
65    if fuzzer.gen_ratio(fuzzer.conf.select_authentication_mutation_rate) {
66        let mutation_strategy: MutationStrategy = if !data.is_empty() {
67            fuzzer.rng.gen_range(MutationStrategy::range()).into()
68        } else {
69            MutationStrategy::ExtendRandom
70        };
71
72        println!(
73            "[i] Mutating Select authentication data of len {} with strategy {:?}",
74            data.len(),
75            mutation_strategy
76        );
77
78        match mutation_strategy {
79            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
80            MutationStrategy::ExtendRandom => {
81                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
82            }
83            MutationStrategy::ExtendCopy => {
84                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
85            }
86            MutationStrategy::Shrink => {
87                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
88            }
89        }
90    }
91}
92
93pub fn mutate_select_multiplexing(fuzzer: &mut FuzzerState, data: &mut Data) {
94    if fuzzer.gen_ratio(fuzzer.conf.select_multiplexing_mutation_rate) {
95        let mutation_strategy: MutationStrategy = if !data.is_empty() {
96            fuzzer.rng.gen_range(MutationStrategy::range()).into()
97        } else {
98            MutationStrategy::ExtendRandom
99        };
100
101        println!(
102            "[i] Mutating Select multiplexing data of len {} with strategy {:?}",
103            data.len(),
104            mutation_strategy
105        );
106
107        match mutation_strategy {
108            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
109            MutationStrategy::ExtendRandom => {
110                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
111            }
112            MutationStrategy::ExtendCopy => {
113                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
114            }
115            MutationStrategy::Shrink => {
116                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
117            }
118        }
119    }
120}
121
122pub fn mutate_select_stream(fuzzer: &mut FuzzerState, data: &mut Data) {
123    if fuzzer.gen_ratio(fuzzer.conf.select_stream_mutation_rate) {
124        let mutation_strategy: MutationStrategy = if !data.is_empty() {
125            fuzzer.rng.gen_range(MutationStrategy::range()).into()
126        } else {
127            MutationStrategy::ExtendRandom
128        };
129
130        println!(
131            "[i] Mutating Select stream data of len {} with strategy {:?}",
132            data.len(),
133            mutation_strategy
134        );
135
136        match mutation_strategy {
137            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
138            MutationStrategy::ExtendRandom => {
139                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
140            }
141            MutationStrategy::ExtendCopy => {
142                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
143            }
144            MutationStrategy::Shrink => {
145                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
146            }
147        }
148    }
149}
150
151pub fn mutate_yamux_frame(fuzzer: &mut FuzzerState, data: &mut Data) {
152    if fuzzer.gen_ratio(fuzzer.conf.yamux_frame_mutation_rate) {
153        let mutation_strategy: MutationStrategy = if !data.is_empty() {
154            fuzzer.rng.gen_range(MutationStrategy::range()).into()
155        } else {
156            MutationStrategy::ExtendRandom
157        };
158
159        println!(
160            "[i] Mutating Yamux frame data of len {} with strategy {:?}",
161            data.len(),
162            mutation_strategy
163        );
164
165        match mutation_strategy {
166            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
167            MutationStrategy::ExtendRandom => {
168                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
169            }
170            MutationStrategy::ExtendCopy => {
171                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
172            }
173            MutationStrategy::Shrink => {
174                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
175            }
176        }
177    }
178}
179
180pub fn mutate_identify_msg(fuzzer: &mut FuzzerState, data: &mut Data) {
181    if fuzzer.gen_ratio(fuzzer.conf.identify_msg_mutation_rate) {
182        let mutation_strategy: MutationStrategy = if !data.is_empty() {
183            fuzzer.rng.gen_range(MutationStrategy::range()).into()
184        } else {
185            MutationStrategy::ExtendRandom
186        };
187
188        println!(
189            "[i] Mutating Identify data of len {} with strategy {:?}",
190            data.len(),
191            mutation_strategy
192        );
193
194        match mutation_strategy {
195            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
196            MutationStrategy::ExtendRandom => {
197                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
198            }
199            MutationStrategy::ExtendCopy => {
200                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
201            }
202            MutationStrategy::Shrink => {
203                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
204            }
205        }
206    }
207}
208
209pub fn mutate_yamux_flags(fuzzer: &mut FuzzerState, flags: &mut YamuxFlags) {
210    if fuzzer.gen_ratio(fuzzer.conf.yamux_flags_mutation_rate) {
211        let new_flags = YamuxFlags::from_bits_truncate(fuzzer.rng.gen());
212        println!("[i] Mutating flags {:?} -> {:?}", flags, new_flags);
213
214        *flags = new_flags;
215    }
216}
217
218pub fn mutate_kad_data(fuzzer: &mut FuzzerState, data: &mut Data) {
219    if fuzzer.gen_ratio(fuzzer.conf.kad_data_mutation_rate) {
220        let mutation_strategy: MutationStrategy = if !data.is_empty() {
221            fuzzer.rng.gen_range(MutationStrategy::range()).into()
222        } else {
223            MutationStrategy::ExtendRandom
224        };
225
226        println!(
227            "[i] Mutating Kad data of len {} with strategy {:?}",
228            data.len(),
229            mutation_strategy
230        );
231
232        match mutation_strategy {
233            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
234            MutationStrategy::ExtendRandom => {
235                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
236            }
237            MutationStrategy::ExtendCopy => {
238                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
239            }
240            MutationStrategy::Shrink => {
241                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
242            }
243        }
244    }
245}
246
247pub fn mutate_rpc_data(fuzzer: &mut FuzzerState, data: &mut Data) {
248    if fuzzer.gen_ratio(fuzzer.conf.rpc_data_mutation_rate) {
249        let mutation_strategy: MutationStrategy = if !data.is_empty() {
250            fuzzer.rng.gen_range(MutationStrategy::range()).into()
251        } else {
252            MutationStrategy::ExtendRandom
253        };
254
255        println!(
256            "[i] Mutating RPC data of len {} with strategy {:?}",
257            data.len(),
258            mutation_strategy
259        );
260
261        match mutation_strategy {
262            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
263            MutationStrategy::ExtendRandom => {
264                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
265            }
266            MutationStrategy::ExtendCopy => {
267                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
268            }
269            MutationStrategy::Shrink => {
270                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
271            }
272        }
273    }
274}
275
276pub fn mutate_pubsub(fuzzer: &mut FuzzerState, data: &mut Data) {
277    if fuzzer.gen_ratio(fuzzer.conf.pubsub_mutation_rate) {
278        let mutation_strategy: MutationStrategy = if !data.is_empty() {
279            fuzzer.rng.gen_range(MutationStrategy::range()).into()
280        } else {
281            MutationStrategy::ExtendRandom
282        };
283
284        println!(
285            "[i] Mutating PubSub data of len {} with strategy {:?}",
286            data.len(),
287            mutation_strategy
288        );
289
290        match mutation_strategy {
291            MutationStrategy::FlipBits => fuzzer.flip_bytes(data.0.as_mut()),
292            MutationStrategy::ExtendRandom => {
293                data.0 = fuzzer.extend_random(data.0.as_ref()).as_slice().into();
294            }
295            MutationStrategy::ExtendCopy => {
296                data.0 = fuzzer.extend_copy(data.0.as_ref()).as_slice().into();
297            }
298            MutationStrategy::Shrink => {
299                data.0 = fuzzer.shrink(data.0.as_ref()).as_slice().into();
300            }
301        }
302    }
303}