linux/tools
Andrii Nakryiko 1216640938 bpf: Switch BPF verifier log to be a rotating log by default
Currently, if user-supplied log buffer to collect BPF verifier log turns
out to be too small to contain full log, bpf() syscall returns -ENOSPC,
fails BPF program verification/load, and preserves first N-1 bytes of
the verifier log (where N is the size of user-supplied buffer).

This is problematic in a bunch of common scenarios, especially when
working with real-world BPF programs that tend to be pretty complex as
far as verification goes and require big log buffers. Typically, it's
when debugging tricky cases at log level 2 (verbose). Also, when BPF program
is successfully validated, log level 2 is the only way to actually see
verifier state progression and all the important details.

Even with log level 1, it's possible to get -ENOSPC even if the final
verifier log fits in log buffer, if there is a code path that's deep
enough to fill up entire log, even if normally it would be reset later
on (there is a logic to chop off successfully validated portions of BPF
verifier log).

In short, it's not always possible to pre-size log buffer. Also, what's
worse, in practice, the end of the log most often is way more important
than the beginning, but verifier stops emitting log as soon as initial
log buffer is filled up.

This patch switches BPF verifier log behavior to effectively behave as
rotating log. That is, if user-supplied log buffer turns out to be too
short, verifier will keep overwriting previously written log,
effectively treating user's log buffer as a ring buffer. -ENOSPC is
still going to be returned at the end, to notify user that log contents
was truncated, but the important last N bytes of the log would be
returned, which might be all that user really needs. This consistent
-ENOSPC behavior, regardless of rotating or fixed log behavior, allows
to prevent backwards compatibility breakage. The only user-visible
change is which portion of verifier log user ends up seeing *if buffer
is too small*. Given contents of verifier log itself is not an ABI,
there is no breakage due to this behavior change. Specialized tools that
rely on specific contents of verifier log in -ENOSPC scenario are
expected to be easily adapted to accommodate old and new behaviors.

Importantly, though, to preserve good user experience and not require
every user-space application to adopt to this new behavior, before
exiting to user-space verifier will rotate log (in place) to make it
start at the very beginning of user buffer as a continuous
zero-terminated string. The contents will be a chopped off N-1 last
bytes of full verifier log, of course.

Given beginning of log is sometimes important as well, we add
BPF_LOG_FIXED (which equals 8) flag to force old behavior, which allows
tools like veristat to request first part of verifier log, if necessary.
BPF_LOG_FIXED flag is also a simple and straightforward way to check if
BPF verifier supports rotating behavior.

On the implementation side, conceptually, it's all simple. We maintain
64-bit logical start and end positions. If we need to truncate the log,
start position will be adjusted accordingly to lag end position by
N bytes. We then use those logical positions to calculate their matching
actual positions in user buffer and handle wrap around the end of the
buffer properly. Finally, right before returning from bpf_check(), we
rotate user log buffer contents in-place as necessary, to make log
contents contiguous. See comments in relevant functions for details.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Lorenz Bauer <lmb@isovalent.com>
Link: https://lore.kernel.org/bpf/20230406234205.323208-4-andrii@kernel.org
2023-04-11 18:05:43 +02:00
..
accounting tools/accounting/procacct: remove some unused variables 2022-11-18 13:55:09 -08:00
arch bpf-next-for-netdev 2023-03-06 20:36:39 -08:00
bootconfig tools/bootconfig: fix single & used for logical condition 2023-02-22 08:27:35 +09:00
bpf bpftool: Set program type only if it differs from the desired one 2023-04-07 15:28:12 -07:00
build tools build: Add test echo-cmd 2023-02-03 13:54:22 -03:00
certs
cgroup tools:cgroup:memcg_shrinker remove redundant import 2023-01-18 17:12:59 -08:00
counter
debugging
edid
firewire
firmware
gpio tools: gpio: fix -c option of gpio-event-mon 2023-01-27 14:05:46 +01:00
hv
iio tools/iio/iio_utils:fix memory leak 2023-01-21 17:52:26 +00:00
include bpf: Update the struct_ops of a bpf_link. 2023-03-22 22:53:02 -07:00
io_uring
kvm/kvm_stat tools/kvm_stat: update exit reasons for vmx/svm/aarch64/userspace 2022-11-09 12:26:52 -05:00
laptop
leds
lib libbpf: disassociate section handler on explicit bpf_program__set_type() call 2023-03-29 17:22:01 -07:00
memory-model tools: memory-model: Make plain accesses carry dependencies 2023-01-03 20:47:04 -08:00
mm tools/mm: allow users to provide additional cflags/ldflags 2023-02-02 22:33:24 -08:00
net/ynl tools: net: add __pycache__ to gitignore 2023-02-24 11:55:47 -08:00
objtool - Daniel Verkamp has contributed a memfd series ("mm/memfd: add 2023-02-23 17:09:35 -08:00
pci
pcmcia
perf - Daniel Verkamp has contributed a memfd series ("mm/memfd: add 2023-02-23 17:09:35 -08:00
power platform-drivers-x86 for v6.3-1 2023-02-21 17:32:50 -08:00
rcu
scripts selftests/bpf: Fix cross compilation with CLANG_CROSS_FLAGS 2023-02-22 13:04:55 -08:00
spi
testing bpf: Switch BPF verifier log to be a rotating log by default 2023-04-11 18:05:43 +02:00
thermal
time
tracing tracing updates for 6.3: 2023-02-23 10:20:49 -08:00
usb tools: usb: ffs-aio-example: Fix build error with aarch64-*-gnu-gcc toolchain(s) 2022-11-09 12:37:56 +01:00
verification tools/rv: Remove unneeded semicolon 2023-01-31 19:21:12 -05:00
virtio tools/virtio: enable to build with retpoline 2023-02-20 19:26:59 -05:00
wmi
Makefile