Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/fuzz.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ main()
-DCONFIG_SYS_HEAP_BIG_ONLY=y
-DCONFIG_ZEPHYR_NATIVE_DRIVERS=y
-DCONFIG_ARCH_POSIX_LIBFUZZER=y
-DCONFIG_ARCH_POSIX_FUZZ_TICKS=100
-DCONFIG_ZEPHYR_POSIX_FUZZ_TICKS=100
-DCONFIG_ASAN=y
)

Expand Down
22 changes: 22 additions & 0 deletions src/platform/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ config ZEPHYR_POSIX
and thus able to instrument and test the whole OS
environment.

if ZEPHYR_POSIX && ARCH_POSIX_LIBFUZZER

config ZEPHYR_POSIX_FUZZ_IRQ
int "OS interrupt via which to deliver fuzz cases"
default 31
help
New fuzz cases are delivered to Zephyr via interrupts. The
IRQ should be otherwise unused, but can be any value desired
by the app.

config ZEPHYR_POSIX_FUZZ_TICKS
int "Ticks to allow for fuzz case processing"
default 2
help
Fuzz interrupts are delivered, from the perspective of the
OS, at a steady cadence in simulated time. In general most
apps won't require much time to reach an idle state
following a unit-test style case, so the default is short to
prevent interaction with regular timer workloads.

endif # ZEPHYR_POSIX && ARCH_POSIX_LIBFUZZER

config IMX8
bool "Build for NXP i.MX8"
select XT_HAVE_RESET_VECTOR_ROM
Expand Down
47 changes: 47 additions & 0 deletions src/platform/posix/fuzz.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright(c) 2024 Google LLC. All rights reserved.
// Author: Andy Ross <andyross@google.com>

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#include <irq_ctrl.h>
#include <zephyr/sys/time_units.h>

/* Zephyr arch APIs, not in a header (native_sim has them though) */
void posix_init(int argc, char *argv[]);
void posix_exec_for(uint64_t us);

const uint8_t *posix_fuzz_buf;
size_t posix_fuzz_sz;

/**
* Entry point for fuzzing. Works by placing the data
* into two known symbols, triggering an app-visible interrupt, and
* then letting the simulator run for a fixed amount of time (intended to be
* "long enough" to handle the event and reach a quiescent state
* again)
*/
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz)
{
static bool runner_initialized;

if (!runner_initialized) {
posix_init(0, NULL);
runner_initialized = true;
}

/* Provide the fuzz data to the embedded OS as an interrupt, with
* "DMA-like" data placed into native_fuzz_buf/sz
*/
posix_fuzz_buf = (void *)data;
posix_fuzz_sz = sz;
hw_irq_ctrl_set_irq(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ);

/* Give the OS time to process whatever happened in that
* interrupt and reach an idle state.
*/
posix_exec_for(k_ticks_to_us_ceil64(CONFIG_ZEPHYR_POSIX_FUZZ_TICKS));
return 0;
}
8 changes: 4 additions & 4 deletions src/platform/posix/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static uint8_t fuzz_in_sz;
// synchronously as another message after receipt of "complete_cmd()"
// from the SOF engine, etc... Eventually we'll receive another fuzz
// input after some amount of simulated time has passed (c.f.
// CONFIG_ARCH_POSIX_FUZZ_TICKS)
// CONFIG_ZEPHYR_POSIX_FUZZ_TICKS)
static void fuzz_isr(const void *arg)
{
size_t rem, i, n = MIN(posix_fuzz_sz, sizeof(fuzz_in) - fuzz_in_sz);
Expand Down Expand Up @@ -179,7 +179,7 @@ void ipc_platform_complete_cmd(struct ipc *ipc)

if (fuzz_in_sz > 0) {
posix_fuzz_sz = 0;
posix_sw_set_pending_IRQ(CONFIG_ARCH_POSIX_FUZZ_IRQ);
posix_sw_set_pending_IRQ(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ);
}
}

Expand All @@ -203,8 +203,8 @@ void ipc_platform_send_msg_direct(const struct ipc_msg *msg)

int platform_ipc_init(struct ipc *ipc)
{
IRQ_CONNECT(CONFIG_ARCH_POSIX_FUZZ_IRQ, 0, fuzz_isr, NULL, 0);
irq_enable(CONFIG_ARCH_POSIX_FUZZ_IRQ);
IRQ_CONNECT(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ, 0, fuzz_isr, NULL, 0);
irq_enable(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ);

global_ipc = ipc;
schedule_task_init_edf(&ipc->ipc_task, SOF_UUID(ipc_task_uuid),
Expand Down
1 change: 1 addition & 0 deletions zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ zephyr_library_sources_ifdef(CONFIG_ZEPHYR_POSIX
${SOF_PLATFORM_PATH}/posix/dai.c
${SOF_PLATFORM_PATH}/posix/ipc.c
${SOF_PLATFORM_PATH}/posix/posix.c
${SOF_PLATFORM_PATH}/posix/fuzz.c
)

zephyr_library_sources_ifdef(CONFIG_LIBRARY
Expand Down