Skip to content

Commit

Permalink
platform/posix: Unbreak fuzzer support
Browse files Browse the repository at this point in the history
Upstream Zephyr moved the LLVM fuzzer entry point out of the arch
layer and made it an app responsibility, so we broke.  Add back the
support here that got removed.

Signed-off-by: Andy Ross <[email protected]>
  • Loading branch information
andyross committed May 7, 2024
1 parent 0ea0d62 commit 406b580
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
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 <[email protected]>

#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 @@ -335,6 +335,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
${SOF_PLATFORM_PATH}/posix/base_fw_platform.c
)

Expand Down

0 comments on commit 406b580

Please sign in to comment.