unix: Add aflplusplus variant for fuzzing.

Signed-off-by: Jeff Epler <jepler@gmail.com>
This commit is contained in:
Jeff Epler 2025-07-21 13:31:39 -05:00
parent ab1986ec0b
commit 03b6cfd0d6
6 changed files with 112 additions and 0 deletions

View file

@ -640,6 +640,10 @@ MP_NOINLINE int main_(int argc, char **argv) {
sys_set_excecutable(argv[0]);
#endif
#ifdef __AFL_HAVE_MANUAL_CONTROL
__AFL_INIT();
#endif
const int NOTHING_EXECUTED = -2;
int ret = NOTHING_EXECUTED;
bool inspect = false;

View file

@ -0,0 +1,24 @@
# Unix Fuzzing Variant
This variant is for use with the [AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
fuzzer.
1. Install AFLplusplus so that the program `afl-cc` is on $PATH
1. `cd ports/unix && make VARIANT=aflplusplus -j$(nproc)`
1. Gather your inputs (e.g., from test cases in `tests`)
1. Optionally, minimize them e.g., with `afl-cmin` (see AFLplusplus docs)
1. Run the fuzzer. The simplest single process way is: `afl-fuzz -i inputs -o findings -- ports/unix/build-aflfuzz/micropython @@`
Eventually, if crashing test cases are found, the crashing program(s) are placed in
`findings/default/crashes` and invocations that were determined to hang go to
`findings/default/hangs`.
There are many more advanced ways to run the fuzzer; see the AFLplusplus documentation for info.
# Safety
Functionality that is known to be unsafe (host filesystem write access via vfs_posix)
or is accepted as causing crashes when used improperly (ctypes, certain struct
& array typecodes) is build-time disabled. However, it's always possible that
the fuzzer will find a condition that can cause an unexpected modification to
the runtime environment.

View file

@ -0,0 +1,3 @@
include("$(PORT_DIR)/variants/manifest.py")
include("$(MPY_DIR)/extmod/asyncio")

View file

@ -0,0 +1,60 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Set base feature level.
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
// Disable features known to affect host environment, access arbitrary addresses, or
// execute arbitrary code
#define MICROPY_VFS_POSIX_WRITABLE (0)
#define MICROPY_PY_STRUCT_UNSAFE_TYPECODES (0)
#define MICROPY_PY_UCTYPES (0)
#define MICROPY_PERSISTENT_CODE_LOAD (0)
// https://github.com/micropython/micropython/issues/17818
#define MICROPY_PY_WEBSOCKET (0)
// https://github.com/micropython/micropython/issues/17714
#define MICROPY_PY_MACHINE (0)
#define MICROPY_EMIT_X64 (0)
#define MICROPY_EMIT_X86 (0)
#define MICROPY_EMIT_THUMB (0)
#define MICROPY_EMIT_INLINE_THUMB (0)
#define MICROPY_EMIT_INLINE_THUMB_FLOAT (0)
#define MICROPY_EMIT_ARM (0)
#define MICROPY_EMIT_XTENSA (0)
#define MICROPY_EMIT_INLINE_XTENSA (0)
#define MICROPY_EMIT_XTENSAWIN (0)
#define MICROPY_EMIT_RV32 (0)
#define MICROPY_EMIT_INLINE_RV32 (0)
#define MICROPY_EMIT_NATIVE_DEBUG (1)
#define MICROPY_EMIT_NATIVE_DEBUG_PRINTER (&mp_stderr_print)
// Enable extra Unix features.
#include "../mpconfigvariant_common.h"

View file

@ -0,0 +1,15 @@
# This is for fuzzing with AFLplusplus
# Disable optimisations and enable assert() on coverage builds.
DEBUG ?= 1
CC=afl-cc
CFLAGS += \
-Wformat -Wmissing-declarations -Wmissing-prototypes \
-Wold-style-definition -Wpointer-arith -Wshadow -Wuninitialized -Wunused-parameter \
MICROPY_PY_SSL = 0
MICROPY_PY_FFI = 0
MPY_TOOL_FLAGS = -mlongint-impl longlong

View file

@ -70,7 +70,9 @@
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (256)
// Allow loading of .mpy files.
#ifndef MICROPY_PERSISTENT_CODE_LOAD
#define MICROPY_PERSISTENT_CODE_LOAD (1)
#endif
// Extra memory debugging.
#define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1)
@ -115,10 +117,14 @@
#define MICROPY_PY_SELECT_SELECT (0)
// Enable the "websocket" module.
#ifndef MICROPY_PY_WEBSOCKET
#define MICROPY_PY_WEBSOCKET (1)
#endif
// Enable the "machine" module, mostly for machine.mem*.
#ifndef MICROPY_PY_MACHINE
#define MICROPY_PY_MACHINE (1)
#endif
#define MICROPY_PY_MACHINE_PULSE (1)
#define MICROPY_PY_MACHINE_PIN_BASE (1)