xref: /aosp_15_r20/external/AFLplusplus/src/afl-fuzz-python.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1 /*
2    american fuzzy lop++ - python extension routines
3    ------------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Now maintained by Marc Heuse <[email protected]>,
8                         Heiko Eißfeldt <[email protected]> and
9                         Andrea Fioraldi <[email protected]>
10 
11    Copyright 2016, 2017 Google Inc. All rights reserved.
12    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
13 
14    Licensed under the Apache License, Version 2.0 (the "License");
15    you may not use this file except in compliance with the License.
16    You may obtain a copy of the License at:
17 
18      https://www.apache.org/licenses/LICENSE-2.0
19 
20    This is the real deal: the program takes an instrumented binary and
21    attempts a variety of basic fuzzing tricks, paying close attention to
22    how they affect the execution path.
23 
24  */
25 
26 #include "afl-fuzz.h"
27 
28 /* Python stuff */
29 #ifdef USE_PYTHON
30 
31 // Tries to cast a python bytearray or bytes to a char ptr
py_bytes(PyObject * py_value,char ** bytes,size_t * size)32 static inline bool py_bytes(PyObject *py_value, /* out */ char **bytes,
33                             /* out */ size_t *size) {
34 
35   if (!py_value) { return false; }
36 
37   *bytes = PyByteArray_AsString(py_value);
38   if (*bytes) {
39 
40     // we got a bytearray
41     *size = PyByteArray_Size(py_value);
42 
43   } else {
44 
45     *bytes = PyBytes_AsString(py_value);
46     if (!*bytes) {
47 
48       // No valid type returned.
49       return false;
50 
51     }
52 
53     *size = PyBytes_Size(py_value);
54 
55   }
56 
57   return true;
58 
59 }
60 
unsupported(afl_state_t * afl,unsigned int seed)61 static void *unsupported(afl_state_t *afl, unsigned int seed) {
62 
63   (void)afl;
64   (void)seed;
65 
66   FATAL("Python Mutator cannot be called twice yet");
67   return NULL;
68 
69 }
70 
71   /* sorry for this makro...
72   it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
73   #define BUF_PARAMS(name) (void **)&((py_mutator_t *)py_mutator)->name##_buf
74 
fuzz_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf,u8 * add_buf,size_t add_buf_size,size_t max_size)75 static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
76                       u8 *add_buf, size_t add_buf_size, size_t max_size) {
77 
78   size_t    mutated_size;
79   PyObject *py_args, *py_value;
80   py_args = PyTuple_New(3);
81   py_mutator_t *py = (py_mutator_t *)py_mutator;
82 
83   /* buf */
84   py_value = PyByteArray_FromStringAndSize(buf, buf_size);
85   if (!py_value) {
86 
87     Py_DECREF(py_args);
88     FATAL("Failed to convert arguments");
89 
90   }
91 
92   PyTuple_SetItem(py_args, 0, py_value);
93 
94   /* add_buf */
95   py_value = PyByteArray_FromStringAndSize(add_buf, add_buf_size);
96   if (!py_value) {
97 
98     Py_DECREF(py_args);
99     FATAL("Failed to convert arguments");
100 
101   }
102 
103   PyTuple_SetItem(py_args, 1, py_value);
104 
105   /* max_size */
106   #if PY_MAJOR_VERSION >= 3
107   py_value = PyLong_FromLong(max_size);
108   #else
109   py_value = PyInt_FromLong(max_size);
110   #endif
111   if (!py_value) {
112 
113     Py_DECREF(py_args);
114     FATAL("Failed to convert arguments");
115 
116   }
117 
118   PyTuple_SetItem(py_args, 2, py_value);
119 
120   py_value = PyObject_CallObject(py->py_functions[PY_FUNC_FUZZ], py_args);
121 
122   Py_DECREF(py_args);
123 
124   if (py_value != NULL) {
125 
126     char *bytes;
127     if (!py_bytes(py_value, &bytes, &mutated_size)) {
128 
129       FATAL("Python mutator fuzz() should return a bytearray or bytes");
130 
131     }
132 
133     if (mutated_size) {
134 
135       *out_buf = afl_realloc(BUF_PARAMS(fuzz), mutated_size);
136       if (unlikely(!*out_buf)) { PFATAL("alloc"); }
137 
138       memcpy(*out_buf, bytes, mutated_size);
139 
140     }
141 
142     Py_DECREF(py_value);
143     return mutated_size;
144 
145   } else {
146 
147     PyErr_Print();
148     FATAL("python custom fuzz: call failed");
149 
150   }
151 
152 }
153 
custom_describe_py(void * py_mutator,size_t max_description_len)154 static const char *custom_describe_py(void  *py_mutator,
155                                       size_t max_description_len) {
156 
157   PyObject *py_args, *py_value;
158 
159   py_args = PyTuple_New(1);
160 
161   PyLong_FromSize_t(max_description_len);
162 
163   /* add_buf */
164   py_value = PyLong_FromSize_t(max_description_len);
165   if (!py_value) {
166 
167     Py_DECREF(py_args);
168     FATAL("Failed to convert arguments");
169 
170   }
171 
172   PyTuple_SetItem(py_args, 0, py_value);
173 
174   py_value = PyObject_CallObject(
175       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DESCRIBE], py_args);
176 
177   Py_DECREF(py_args);
178 
179   if (py_value != NULL) { return PyBytes_AsString(py_value); }
180 
181   return NULL;
182 
183 }
184 
init_py_module(afl_state_t * afl,u8 * module_name)185 static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
186 
187   (void)afl;
188 
189   if (!module_name) { return NULL; }
190 
191   py_mutator_t *py = calloc(1, sizeof(py_mutator_t));
192   if (!py) { PFATAL("Could not allocate memory for python mutator!"); }
193 
194   Py_Initialize();
195 
196   #if PY_MAJOR_VERSION >= 3
197   PyObject *py_name = PyUnicode_FromString(module_name);
198   #else
199   PyObject *py_name = PyString_FromString(module_name);
200   #endif
201 
202   py->py_module = PyImport_Import(py_name);
203   Py_DECREF(py_name);
204 
205   PyObject  *py_module = py->py_module;
206   PyObject **py_functions = py->py_functions;
207 
208   // initialize the post process buffer; ensures it's always valid
209   PyObject *unused_bytes = PyByteArray_FromStringAndSize("OHAI", 4);
210   if (!unused_bytes) { FATAL("allocation failed!"); }
211   if (PyObject_GetBuffer(unused_bytes, &py->post_process_buf, PyBUF_SIMPLE) ==
212       -1) {
213 
214     FATAL("buffer initialization failed");
215 
216   }
217 
218   Py_DECREF(unused_bytes);
219 
220   if (py_module != NULL) {
221 
222     u8 py_notrim = 0;
223     py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init");
224     if (!py_functions[PY_FUNC_INIT]) {
225 
226       WARNF("init function not found in python module");
227 
228     }
229 
230     py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz");
231     if (!py_functions[PY_FUNC_FUZZ])
232       py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate");
233     py_functions[PY_FUNC_DESCRIBE] =
234         PyObject_GetAttrString(py_module, "describe");
235     py_functions[PY_FUNC_FUZZ_COUNT] =
236         PyObject_GetAttrString(py_module, "fuzz_count");
237     py_functions[PY_FUNC_POST_PROCESS] =
238         PyObject_GetAttrString(py_module, "post_process");
239     py_functions[PY_FUNC_INIT_TRIM] =
240         PyObject_GetAttrString(py_module, "init_trim");
241     py_functions[PY_FUNC_POST_TRIM] =
242         PyObject_GetAttrString(py_module, "post_trim");
243     py_functions[PY_FUNC_TRIM] = PyObject_GetAttrString(py_module, "trim");
244     py_functions[PY_FUNC_HAVOC_MUTATION] =
245         PyObject_GetAttrString(py_module, "havoc_mutation");
246     py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY] =
247         PyObject_GetAttrString(py_module, "havoc_mutation_probability");
248     py_functions[PY_FUNC_QUEUE_GET] =
249         PyObject_GetAttrString(py_module, "queue_get");
250     py_functions[PY_FUNC_FUZZ_SEND] =
251         PyObject_GetAttrString(py_module, "fuzz_send");
252     py_functions[PY_FUNC_POST_RUN] =
253         PyObject_GetAttrString(py_module, "post_run");
254     py_functions[PY_FUNC_SPLICE_OPTOUT] =
255         PyObject_GetAttrString(py_module, "splice_optout");
256     if (py_functions[PY_FUNC_SPLICE_OPTOUT]) { afl->custom_splice_optout = 1; }
257     py_functions[PY_FUNC_QUEUE_NEW_ENTRY] =
258         PyObject_GetAttrString(py_module, "queue_new_entry");
259     py_functions[PY_FUNC_INTROSPECTION] =
260         PyObject_GetAttrString(py_module, "introspection");
261     py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit");
262     if (!py_functions[PY_FUNC_DEINIT])
263       WARNF("deinit function not found in python module");
264 
265     if (py_notrim) {
266 
267       py_functions[PY_FUNC_INIT_TRIM] = NULL;
268       py_functions[PY_FUNC_POST_TRIM] = NULL;
269       py_functions[PY_FUNC_TRIM] = NULL;
270       WARNF(
271           "Python module does not implement trim API, standard trimming will "
272           "be used.");
273 
274     }
275 
276   } else {
277 
278     PyErr_Print();
279     fprintf(stderr, "Failed to load \"%s\"\n", module_name);
280     free(py);
281     return NULL;
282 
283   }
284 
285   return py;
286 
287 }
288 
finalize_py_module(void * py_mutator)289 void finalize_py_module(void *py_mutator) {
290 
291   py_mutator_t *py = (py_mutator_t *)py_mutator;
292 
293   if (py->py_module != NULL) {
294 
295     deinit_py(py_mutator);
296 
297     u32 i;
298     for (i = 0; i < PY_FUNC_COUNT; ++i) {
299 
300       Py_XDECREF(py->py_functions[i]);
301 
302     }
303 
304     Py_DECREF(py->py_module);
305 
306   }
307 
308   Py_Finalize();
309 
310 }
311 
init_py(afl_state_t * afl,py_mutator_t * py_mutator,unsigned int seed)312 static void init_py(afl_state_t *afl, py_mutator_t *py_mutator,
313                     unsigned int seed) {
314 
315   (void)afl;
316 
317   if (py_mutator->py_functions[PY_FUNC_INIT] == NULL) { return; }
318 
319   PyObject *py_args, *py_value;
320 
321   /* Provide the init function a seed for the Python RNG */
322   py_args = PyTuple_New(1);
323   #if PY_MAJOR_VERSION >= 3
324   py_value = PyLong_FromLong(seed);
325   #else
326   py_value = PyInt_FromLong(seed);
327   #endif
328 
329   if (!py_value) {
330 
331     Py_DECREF(py_args);
332     FATAL("Cannot convert argument in python init.");
333 
334   }
335 
336   PyTuple_SetItem(py_args, 0, py_value);
337 
338   py_value =
339       PyObject_CallObject(py_mutator->py_functions[PY_FUNC_INIT], py_args);
340 
341   Py_DECREF(py_args);
342 
343   if (py_value == NULL) {
344 
345     PyErr_Print();
346     fprintf(stderr, "Call failed\n");
347     FATAL("Custom py mutator INIT failed.");
348 
349   }
350 
351 }
352 
deinit_py(void * py_mutator)353 void deinit_py(void *py_mutator) {
354 
355   PyObject *py_args, *py_value;
356 
357   py_args = PyTuple_New(0);
358   py_value = PyObject_CallObject(
359       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_DEINIT], py_args);
360   Py_DECREF(py_args);
361 
362   if (py_value != NULL) {
363 
364     Py_DECREF(py_value);
365 
366   } else {
367 
368     PyErr_Print();
369     FATAL("Call failed");
370 
371   }
372 
373 }
374 
splice_optout_py(void * py_mutator)375 void splice_optout_py(void *py_mutator) {
376 
377   // this is never called
378   (void)(py_mutator);
379 
380 }
381 
load_custom_mutator_py(afl_state_t * afl,char * module_name)382 struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
383                                               char        *module_name) {
384 
385   struct custom_mutator *mutator;
386 
387   mutator = ck_alloc(sizeof(struct custom_mutator));
388   mutator->name = module_name;
389   ACTF("Loading Python mutator library from '%s'...", module_name);
390 
391   if (memchr(module_name, '/', strlen(module_name))) {
392 
393     mutator->name_short = strdup(strrchr(module_name, '/') + 1);
394 
395   } else {
396 
397     mutator->name_short = strdup(module_name);
398 
399   }
400 
401   if (strlen(mutator->name_short) > 22) { mutator->name_short[21] = 0; }
402 
403   py_mutator_t *py_mutator;
404   py_mutator = init_py_module(afl, module_name);
405   mutator->data = py_mutator;
406   if (!py_mutator) { FATAL("Failed to load python mutator."); }
407 
408   PyObject **py_functions = py_mutator->py_functions;
409 
410   if (py_functions[PY_FUNC_INIT]) { mutator->afl_custom_init = unsupported; }
411 
412   if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; }
413 
414   if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; }
415 
416   if (py_functions[PY_FUNC_DESCRIBE]) {
417 
418     mutator->afl_custom_describe = custom_describe_py;
419 
420   }
421 
422   if (py_functions[PY_FUNC_POST_PROCESS]) {
423 
424     mutator->afl_custom_post_process = post_process_py;
425 
426   }
427 
428   if (py_functions[PY_FUNC_INIT_TRIM]) {
429 
430     mutator->afl_custom_init_trim = init_trim_py;
431 
432   }
433 
434   if (py_functions[PY_FUNC_FUZZ_COUNT]) {
435 
436     mutator->afl_custom_fuzz_count = fuzz_count_py;
437 
438   }
439 
440   if (py_functions[PY_FUNC_POST_TRIM]) {
441 
442     mutator->afl_custom_post_trim = post_trim_py;
443 
444   }
445 
446   if (py_functions[PY_FUNC_TRIM]) { mutator->afl_custom_trim = trim_py; }
447 
448   if (py_functions[PY_FUNC_HAVOC_MUTATION]) {
449 
450     mutator->afl_custom_havoc_mutation = havoc_mutation_py;
451 
452   }
453 
454   if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY]) {
455 
456     mutator->afl_custom_havoc_mutation_probability =
457         havoc_mutation_probability_py;
458 
459   }
460 
461   if (py_functions[PY_FUNC_QUEUE_GET]) {
462 
463     mutator->afl_custom_queue_get = queue_get_py;
464 
465   }
466 
467   if (py_functions[PY_FUNC_FUZZ_SEND]) {
468 
469     mutator->afl_custom_fuzz_send = fuzz_send_py;
470 
471   }
472 
473   if (py_functions[PY_FUNC_POST_RUN]) {
474 
475     mutator->afl_custom_post_run = post_run_py;
476 
477   }
478 
479   if (py_functions[PY_FUNC_SPLICE_OPTOUT]) {
480 
481     mutator->afl_custom_splice_optout = splice_optout_py;
482     afl->custom_splice_optout = 1;
483 
484   }
485 
486   if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) {
487 
488     mutator->afl_custom_queue_new_entry = queue_new_entry_py;
489 
490   }
491 
492   #ifdef INTROSPECTION
493   if (py_functions[PY_FUNC_INTROSPECTION]) {
494 
495     mutator->afl_custom_introspection = introspection_py;
496 
497   }
498 
499   #endif
500 
501   OKF("Python mutator '%s' installed successfully.", module_name);
502 
503   /* Initialize the custom mutator */
504   init_py(afl, py_mutator, rand_below(afl, 0xFFFFFFFF));
505 
506   mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation);
507   mutator->stacked_custom_prob =
508       6;  // like one of the default mutations in havoc
509 
510   return mutator;
511 
512 }
513 
post_process_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf)514 size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size,
515                        u8 **out_buf) {
516 
517   PyObject     *py_args, *py_value;
518   py_mutator_t *py = (py_mutator_t *)py_mutator;
519 
520   // buffer returned previously must be released; initialized during init
521   // so we don't need to do comparisons
522   PyBuffer_Release(&py->post_process_buf);
523 
524   py_args = PyTuple_New(1);
525   py_value = PyByteArray_FromStringAndSize(buf, buf_size);
526   if (!py_value) {
527 
528     Py_DECREF(py_args);
529     FATAL("Failed to convert arguments in custom post_process");
530 
531   }
532 
533   PyTuple_SetItem(py_args, 0, py_value);
534 
535   py_value = PyObject_CallObject(
536       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_PROCESS],
537       py_args);
538 
539   Py_DECREF(py_args);
540 
541   if (py_value != NULL) {
542 
543     if (PyObject_GetBuffer(py_value, &py->post_process_buf, PyBUF_SIMPLE) ==
544         -1) {
545 
546       PyErr_Print();
547       FATAL(
548           "Python custom mutator: post_process call return value not a "
549           "bytes-like object");
550 
551     }
552 
553     Py_DECREF(py_value);
554 
555     if (unlikely(py->post_process_buf.len == 0)) {
556 
557       *out_buf = NULL;
558 
559     } else {
560 
561       *out_buf = (u8 *)py->post_process_buf.buf;
562 
563     }
564 
565     return py->post_process_buf.len;
566 
567   } else {
568 
569     PyErr_Print();
570     FATAL("Python custom mutator: post_process call failed.");
571 
572   }
573 
574 }
575 
init_trim_py(void * py_mutator,u8 * buf,size_t buf_size)576 s32 init_trim_py(void *py_mutator, u8 *buf, size_t buf_size) {
577 
578   PyObject *py_args, *py_value;
579 
580   py_args = PyTuple_New(1);
581   py_value = PyByteArray_FromStringAndSize(buf, buf_size);
582   if (!py_value) {
583 
584     Py_DECREF(py_args);
585     FATAL("Failed to convert arguments");
586 
587   }
588 
589   PyTuple_SetItem(py_args, 0, py_value);
590 
591   py_value = PyObject_CallObject(
592       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INIT_TRIM], py_args);
593   Py_DECREF(py_args);
594 
595   if (py_value != NULL) {
596 
597   #if PY_MAJOR_VERSION >= 3
598     u32 retcnt = (u32)PyLong_AsLong(py_value);
599   #else
600     u32 retcnt = PyInt_AsLong(py_value);
601   #endif
602     Py_DECREF(py_value);
603     return retcnt;
604 
605   } else {
606 
607     PyErr_Print();
608     FATAL("Call failed");
609 
610   }
611 
612 }
613 
fuzz_count_py(void * py_mutator,const u8 * buf,size_t buf_size)614 u32 fuzz_count_py(void *py_mutator, const u8 *buf, size_t buf_size) {
615 
616   PyObject *py_args, *py_value;
617 
618   py_args = PyTuple_New(1);
619   py_value = PyByteArray_FromStringAndSize(buf, buf_size);
620   if (!py_value) {
621 
622     Py_DECREF(py_args);
623     FATAL("Failed to convert arguments");
624 
625   }
626 
627   PyTuple_SetItem(py_args, 0, py_value);
628 
629   py_value = PyObject_CallObject(
630       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_COUNT], py_args);
631   Py_DECREF(py_args);
632 
633   if (py_value != NULL) {
634 
635   #if PY_MAJOR_VERSION >= 3
636     u32 retcnt = (u32)PyLong_AsLong(py_value);
637   #else
638     u32 retcnt = PyInt_AsLong(py_value);
639   #endif
640     Py_DECREF(py_value);
641     return retcnt;
642 
643   } else {
644 
645     PyErr_Print();
646     FATAL("Call failed");
647 
648   }
649 
650 }
651 
post_trim_py(void * py_mutator,u8 success)652 s32 post_trim_py(void *py_mutator, u8 success) {
653 
654   PyObject *py_args, *py_value;
655 
656   py_args = PyTuple_New(1);
657 
658   py_value = PyBool_FromLong(success);
659   if (!py_value) {
660 
661     Py_DECREF(py_args);
662     FATAL("Failed to convert arguments");
663 
664   }
665 
666   PyTuple_SetItem(py_args, 0, py_value);
667 
668   py_value = PyObject_CallObject(
669       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_TRIM], py_args);
670   Py_DECREF(py_args);
671 
672   if (py_value != NULL) {
673 
674   #if PY_MAJOR_VERSION >= 3
675     u32 retcnt = (u32)PyLong_AsLong(py_value);
676   #else
677     u32 retcnt = PyInt_AsLong(py_value);
678   #endif
679     Py_DECREF(py_value);
680     return retcnt;
681 
682   } else {
683 
684     PyErr_Print();
685     FATAL("Call failed");
686 
687   }
688 
689 }
690 
trim_py(void * py_mutator,u8 ** out_buf)691 size_t trim_py(void *py_mutator, u8 **out_buf) {
692 
693   PyObject *py_args, *py_value;
694   size_t    trimmed_size;
695 
696   py_args = PyTuple_New(0);
697   py_value = PyObject_CallObject(
698       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_TRIM], py_args);
699   Py_DECREF(py_args);
700 
701   if (py_value != NULL) {
702 
703     char *bytes;
704     if (!py_bytes(py_value, &bytes, &trimmed_size)) {
705 
706       FATAL("Python mutator fuzz() should return a bytearray");
707 
708     }
709 
710     if (trimmed_size) {
711 
712       *out_buf = afl_realloc(BUF_PARAMS(trim), trimmed_size);
713       if (unlikely(!*out_buf)) { PFATAL("alloc"); }
714       memcpy(*out_buf, bytes, trimmed_size);
715 
716     }
717 
718     Py_DECREF(py_value);
719 
720   } else {
721 
722     PyErr_Print();
723     FATAL("Call failed");
724 
725   }
726 
727   return trimmed_size;
728 
729 }
730 
havoc_mutation_py(void * py_mutator,u8 * buf,size_t buf_size,u8 ** out_buf,size_t max_size)731 size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size,
732                          u8 **out_buf, size_t max_size) {
733 
734   size_t    mutated_size;
735   PyObject *py_args, *py_value;
736   py_args = PyTuple_New(2);
737 
738   /* buf */
739   py_value = PyByteArray_FromStringAndSize(buf, buf_size);
740   if (!py_value) {
741 
742     Py_DECREF(py_args);
743     FATAL("Failed to convert arguments");
744 
745   }
746 
747   PyTuple_SetItem(py_args, 0, py_value);
748 
749   /* max_size */
750   #if PY_MAJOR_VERSION >= 3
751   py_value = PyLong_FromLong(max_size);
752   #else
753   py_value = PyInt_FromLong(max_size);
754   #endif
755   if (!py_value) {
756 
757     Py_DECREF(py_args);
758     FATAL("Failed to convert arguments");
759 
760   }
761 
762   PyTuple_SetItem(py_args, 1, py_value);
763 
764   py_value = PyObject_CallObject(
765       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_HAVOC_MUTATION],
766       py_args);
767 
768   Py_DECREF(py_args);
769 
770   if (py_value != NULL) {
771 
772     char *bytes;
773     if (!py_bytes(py_value, &bytes, &mutated_size)) {
774 
775       FATAL("Python mutator fuzz() should return a bytearray");
776 
777     }
778 
779     if (mutated_size <= buf_size) {
780 
781       /* We reuse the input buf here. */
782       *out_buf = buf;
783 
784     } else {
785 
786       /* A new buf is needed... */
787       *out_buf = afl_realloc(BUF_PARAMS(havoc), mutated_size);
788       if (unlikely(!*out_buf)) { PFATAL("alloc"); }
789 
790     }
791 
792     if (mutated_size) { memcpy(*out_buf, bytes, mutated_size); }
793 
794     Py_DECREF(py_value);
795     return mutated_size;
796 
797   } else {
798 
799     PyErr_Print();
800     FATAL("Call failed");
801 
802   }
803 
804 }
805 
havoc_mutation_probability_py(void * py_mutator)806 u8 havoc_mutation_probability_py(void *py_mutator) {
807 
808   PyObject *py_args, *py_value;
809 
810   py_args = PyTuple_New(0);
811   py_value = PyObject_CallObject(
812       ((py_mutator_t *)py_mutator)
813           ->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY],
814       py_args);
815   Py_DECREF(py_args);
816 
817   if (py_value != NULL) {
818 
819     long prob = PyLong_AsLong(py_value);
820     Py_DECREF(py_value);
821     return (u8)prob;
822 
823   } else {
824 
825     PyErr_Print();
826     FATAL("Call failed");
827 
828   }
829 
830 }
831 
introspection_py(void * py_mutator)832 const char *introspection_py(void *py_mutator) {
833 
834   PyObject *py_args, *py_value;
835 
836   py_args = PyTuple_New(0);
837   py_value = PyObject_CallObject(
838       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INTROSPECTION],
839       py_args);
840   Py_DECREF(py_args);
841 
842   if (py_value == NULL) {
843 
844     return NULL;
845 
846   } else {
847 
848     char  *ret;
849     size_t len;
850     if (!py_bytes(py_value, &ret, &len)) {
851 
852       FATAL(
853           "Python mutator introspection call returned illegal type (expected "
854           "bytes or bytearray)");
855 
856     }
857 
858     return ret;
859 
860   }
861 
862 }
863 
queue_get_py(void * py_mutator,const u8 * filename)864 u8 queue_get_py(void *py_mutator, const u8 *filename) {
865 
866   PyObject *py_args, *py_value;
867 
868   py_args = PyTuple_New(1);
869 
870   // File name
871   #if PY_MAJOR_VERSION >= 3
872   py_value = PyUnicode_FromString(filename);
873   #else
874   py_value = PyString_FromString(filename);
875   #endif
876   if (!py_value) {
877 
878     Py_DECREF(py_args);
879     FATAL("Failed to convert arguments");
880 
881   }
882 
883   PyTuple_SetItem(py_args, 0, py_value);
884 
885   // Call Python function
886   py_value = PyObject_CallObject(
887       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_GET], py_args);
888   Py_DECREF(py_args);
889 
890   if (py_value != NULL) {
891 
892     int ret = PyObject_IsTrue(py_value);
893     Py_DECREF(py_value);
894 
895     if (ret == -1) {
896 
897       PyErr_Print();
898       FATAL("Failed to convert return value");
899 
900     }
901 
902     return (u8)ret & 0xFF;
903 
904   } else {
905 
906     PyErr_Print();
907     FATAL("Call failed");
908 
909   }
910 
911 }
912 
fuzz_send_py(void * py_mutator,const u8 * buf,size_t buf_size)913 void fuzz_send_py(void *py_mutator, const u8 *buf, size_t buf_size) {
914 
915   PyObject *py_args, *py_value;
916 
917   py_args = PyTuple_New(1);
918   py_value = PyByteArray_FromStringAndSize(buf, buf_size);
919   if (!py_value) {
920 
921     Py_DECREF(py_args);
922     FATAL("Failed to convert arguments");
923 
924   }
925 
926   PyTuple_SetItem(py_args, 0, py_value);
927 
928   py_value = PyObject_CallObject(
929       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_SEND], py_args);
930   Py_DECREF(py_args);
931 
932   if (py_value != NULL) { Py_DECREF(py_value); }
933 
934 }
935 
post_run_py(void * py_mutator)936 void post_run_py(void *py_mutator) {
937 
938   PyObject *py_args, *py_value;
939 
940   py_args = PyTuple_New(0);
941   py_value = PyObject_CallObject(
942       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_POST_RUN], py_args);
943   Py_DECREF(py_args);
944 
945   if (py_value != NULL) {
946 
947     Py_DECREF(py_value);
948 
949   } else {
950 
951     PyErr_Print();
952     FATAL("Call failed");
953 
954   }
955 
956 }
957 
queue_new_entry_py(void * py_mutator,const u8 * filename_new_queue,const u8 * filename_orig_queue)958 u8 queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue,
959                       const u8 *filename_orig_queue) {
960 
961   PyObject *py_args, *py_value;
962 
963   py_args = PyTuple_New(2);
964 
965   // New queue
966   #if PY_MAJOR_VERSION >= 3
967   py_value = PyUnicode_FromString(filename_new_queue);
968   #else
969   py_value = PyString_FromString(filename_new_queue);
970   #endif
971   if (!py_value) {
972 
973     Py_DECREF(py_args);
974     FATAL("Failed to convert arguments");
975 
976   }
977 
978   PyTuple_SetItem(py_args, 0, py_value);
979 
980   // Orig queue
981   py_value = Py_None;
982   if (filename_orig_queue) {
983 
984   #if PY_MAJOR_VERSION >= 3
985     py_value = PyUnicode_FromString(filename_orig_queue);
986   #else
987     py_value = PyString_FromString(filename_orig_queue);
988   #endif
989     if (!py_value) {
990 
991       Py_DECREF(py_args);
992       FATAL("Failed to convert arguments");
993 
994     }
995 
996   }
997 
998   PyTuple_SetItem(py_args, 1, py_value);
999 
1000   // Call
1001   py_value = PyObject_CallObject(
1002       ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_QUEUE_NEW_ENTRY],
1003       py_args);
1004   Py_DECREF(py_args);
1005 
1006   if (py_value != NULL) {
1007 
1008     int ret = PyObject_IsTrue(py_value);
1009     Py_DECREF(py_value);
1010 
1011     if (ret == -1) {
1012 
1013       PyErr_Print();
1014       FATAL("Failed to convert return value");
1015 
1016     }
1017 
1018     return (u8)ret & 0xFF;
1019 
1020   } else {
1021 
1022     PyErr_Print();
1023     FATAL("Call failed");
1024 
1025   }
1026 
1027 }
1028 
1029   #undef BUF_PARAMS
1030 
1031 #endif                                                        /* USE_PYTHON */
1032 
1033