Skip to content

Commit 3beea52

Browse files
committed
platform/posix: Unbreak fuzzer support
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. Fixes #9101 Signed-off-by: Andy Ross <andyross@google.com>
1 parent 4a761f6 commit 3beea52

File tree

5 files changed

+75
-5
lines changed

5 files changed

+75
-5
lines changed

scripts/fuzz.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ main()
112112
-DCONFIG_SYS_HEAP_BIG_ONLY=y
113113
-DCONFIG_ZEPHYR_NATIVE_DRIVERS=y
114114
-DCONFIG_ARCH_POSIX_LIBFUZZER=y
115-
-DCONFIG_ARCH_POSIX_FUZZ_TICKS=100
115+
-DCONFIG_ZEPHYR_POSIX_FUZZ_TICKS=100
116116
-DCONFIG_ASAN=y
117117
)
118118

src/platform/Kconfig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ config ZEPHYR_POSIX
5555
and thus able to instrument and test the whole OS
5656
environment.
5757

58+
if ZEPHYR_POSIX && ARCH_POSIX_LIBFUZZER
59+
60+
config ZEPHYR_POSIX_FUZZ_IRQ
61+
int "OS interrupt via which to deliver fuzz cases"
62+
default 31
63+
help
64+
New fuzz cases are delivered to Zephyr via interrupts. The
65+
IRQ should be otherwise unused, but can be any value desired
66+
by the app.
67+
68+
config ZEPHYR_POSIX_FUZZ_TICKS
69+
int "Ticks to allow for fuzz case processing"
70+
default 2
71+
help
72+
Fuzz interrupts are delivered, from the perspective of the
73+
OS, at a steady cadence in simulated time. In general most
74+
apps won't require much time to reach an idle state
75+
following a unit-test style case, so the default is short to
76+
prevent interaction with regular timer workloads.
77+
78+
endif # ZEPHYR_POSIX && ARCH_POSIX_LIBFUZZER
79+
5880
config IMX8
5981
bool "Build for NXP i.MX8"
6082
select XT_HAVE_RESET_VECTOR_ROM

src/platform/posix/fuzz.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright(c) 2024 Google LLC. All rights reserved.
3+
// Author: Andy Ross <andyross@google.com>
4+
5+
#include <stdint.h>
6+
#include <stddef.h>
7+
#include <stdbool.h>
8+
9+
#include <irq_ctrl.h>
10+
#include <zephyr/sys/time_units.h>
11+
12+
/* Zephyr arch APIs, not in a header (native_sim has them though) */
13+
void posix_init(int argc, char *argv[]);
14+
void posix_exec_for(uint64_t us);
15+
16+
const uint8_t *posix_fuzz_buf;
17+
size_t posix_fuzz_sz;
18+
19+
/**
20+
* Entry point for fuzzing. Works by placing the data
21+
* into two known symbols, triggering an app-visible interrupt, and
22+
* then letting the simulator run for a fixed amount of time (intended to be
23+
* "long enough" to handle the event and reach a quiescent state
24+
* again)
25+
*/
26+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz)
27+
{
28+
static bool runner_initialized;
29+
30+
if (!runner_initialized) {
31+
posix_init(0, NULL);
32+
runner_initialized = true;
33+
}
34+
35+
/* Provide the fuzz data to the embedded OS as an interrupt, with
36+
* "DMA-like" data placed into native_fuzz_buf/sz
37+
*/
38+
posix_fuzz_buf = (void *)data;
39+
posix_fuzz_sz = sz;
40+
hw_irq_ctrl_set_irq(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ);
41+
42+
/* Give the OS time to process whatever happened in that
43+
* interrupt and reach an idle state.
44+
*/
45+
posix_exec_for(k_ticks_to_us_ceil64(CONFIG_ZEPHYR_POSIX_FUZZ_TICKS));
46+
return 0;
47+
}

src/platform/posix/ipc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static uint8_t fuzz_in_sz;
4343
// synchronously as another message after receipt of "complete_cmd()"
4444
// from the SOF engine, etc... Eventually we'll receive another fuzz
4545
// input after some amount of simulated time has passed (c.f.
46-
// CONFIG_ARCH_POSIX_FUZZ_TICKS)
46+
// CONFIG_ZEPHYR_POSIX_FUZZ_TICKS)
4747
static void fuzz_isr(const void *arg)
4848
{
4949
size_t rem, i, n = MIN(posix_fuzz_sz, sizeof(fuzz_in) - fuzz_in_sz);
@@ -179,7 +179,7 @@ void ipc_platform_complete_cmd(struct ipc *ipc)
179179

180180
if (fuzz_in_sz > 0) {
181181
posix_fuzz_sz = 0;
182-
posix_sw_set_pending_IRQ(CONFIG_ARCH_POSIX_FUZZ_IRQ);
182+
posix_sw_set_pending_IRQ(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ);
183183
}
184184
}
185185

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

204204
int platform_ipc_init(struct ipc *ipc)
205205
{
206-
IRQ_CONNECT(CONFIG_ARCH_POSIX_FUZZ_IRQ, 0, fuzz_isr, NULL, 0);
207-
irq_enable(CONFIG_ARCH_POSIX_FUZZ_IRQ);
206+
IRQ_CONNECT(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ, 0, fuzz_isr, NULL, 0);
207+
irq_enable(CONFIG_ZEPHYR_POSIX_FUZZ_IRQ);
208208

209209
global_ipc = ipc;
210210
schedule_task_init_edf(&ipc->ipc_task, SOF_UUID(ipc_task_uuid),

zephyr/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ zephyr_library_sources_ifdef(CONFIG_ZEPHYR_POSIX
333333
${SOF_PLATFORM_PATH}/posix/dai.c
334334
${SOF_PLATFORM_PATH}/posix/ipc.c
335335
${SOF_PLATFORM_PATH}/posix/posix.c
336+
${SOF_PLATFORM_PATH}/posix/fuzz.c
336337
)
337338

338339
zephyr_library_sources_ifdef(CONFIG_LIBRARY

0 commit comments

Comments
 (0)