On Wed, Apr 14, 2021 at 11:54 AM Florent Revest <revest@xxxxxxxxxxxx> wrote: > > The "positive" part tests all format specifiers when things go well. > > The "negative" part makes sure that incorrect format strings fail at > load time. > > Signed-off-by: Florent Revest <revest@xxxxxxxxxxxx> > --- > .../selftests/bpf/prog_tests/snprintf.c | 124 ++++++++++++++++++ > .../selftests/bpf/progs/test_snprintf.c | 73 +++++++++++ > .../bpf/progs/test_snprintf_single.c | 20 +++ > 3 files changed, 217 insertions(+) > create mode 100644 tools/testing/selftests/bpf/prog_tests/snprintf.c > create mode 100644 tools/testing/selftests/bpf/progs/test_snprintf.c > create mode 100644 tools/testing/selftests/bpf/progs/test_snprintf_single.c > [...] > +/* Loads an eBPF object calling bpf_snprintf with up to 10 characters of fmt */ > +static int load_single_snprintf(char *fmt) > +{ > + struct test_snprintf_single *skel; > + int ret; > + > + skel = test_snprintf_single__open(); > + if (!skel) > + return -EINVAL; > + > + memcpy(skel->rodata->fmt, fmt, min(strlen(fmt) + 1, 10)); > + > + ret = test_snprintf_single__load(skel); > + if (!ret) > + test_snprintf_single__destroy(skel); destroy unconditionally? > + > + return ret; > +} > + > +void test_snprintf_negative(void) > +{ > + ASSERT_OK(load_single_snprintf("valid %d"), "valid usage"); > + > + ASSERT_ERR(load_single_snprintf("0123456789"), "no terminating zero"); > + ASSERT_ERR(load_single_snprintf("%d %d"), "too many specifiers"); > + ASSERT_ERR(load_single_snprintf("%pi5"), "invalid specifier 1"); > + ASSERT_ERR(load_single_snprintf("%a"), "invalid specifier 2"); > + ASSERT_ERR(load_single_snprintf("%"), "invalid specifier 3"); > + ASSERT_ERR(load_single_snprintf("\x80"), "non ascii character"); > + ASSERT_ERR(load_single_snprintf("\x1"), "non printable character"); Some more cases that came up in my mind: 1. %123987129387192387 -- long and unterminated specified 2. similarly %------- or something like that Do you think they are worth checking? > +} > + > +void test_snprintf(void) > +{ > + if (test__start_subtest("snprintf_positive")) > + test_snprintf_positive(); > + if (test__start_subtest("snprintf_negative")) > + test_snprintf_negative(); > +} [...] > +char _license[] SEC("license") = "GPL"; > diff --git a/tools/testing/selftests/bpf/progs/test_snprintf_single.c b/tools/testing/selftests/bpf/progs/test_snprintf_single.c > new file mode 100644 > index 000000000000..15ccc5c43803 > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/test_snprintf_single.c > @@ -0,0 +1,20 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright (c) 2021 Google LLC. */ > + > +#include <linux/bpf.h> > +#include <bpf/bpf_helpers.h> > + > +// The format string is filled from the userspace side such that loading fails C++ style format > +static const char fmt[10]; > + > +SEC("raw_tp/sys_enter") > +int handler(const void *ctx) > +{ > + unsigned long long arg = 42; > + > + bpf_snprintf(NULL, 0, fmt, &arg, sizeof(arg)); > + > + return 0; > +} > + > +char _license[] SEC("license") = "GPL"; > -- > 2.31.1.295.g9ea45b61b8-goog >