Repository navigation
Conversation
Stack frames other than the first are return addresses, the address of the instruction after a call. When the call is the last instruction of a function, as it is for calls to noreturn functions, the return address is the first byte of whatever function follows in memory, and looking it up directly names that unrelated function at +0x0. Look up addr - 1 instead, which is what the kernel's %pB format does for backtraces, and keep printing the offset relative to the address itself.
Functions marked __init live in the module's init text, which the kernel
unmaps once the module's init function returns. By the time userspace
reads /proc/kallsyms on the module_load event those symbols are usually
gone, so allocations made during init were attributed to whatever symbol
preceded the freed range.
Resolve them where the information still exists: in the BPF program, at
the time of the allocation. For each recorded allocation, walk the
captured stack and format every return address that falls in the
module's init text with bpf_snprintf("%pS"), storing the result in a
hash map keyed by address. Userspace consults that map before the
kallsyms snapshot when printing a frame. bpf_snprintf() does not accept
%pB, so the lookup is done on the preceding byte and userspace adds one
to the offset, which gives the same attribution as %pB.
Alternatives considered:
- Reading the module's ELF in userspace and relocating its .init.text
symbols with /sys/module/<name>/sections/.init.text, which persists
after init. Works, but needs the .ko path and an ELF parser.
- Copying struct module::kallsyms from the module_load tracepoint. Also
works, but means iterating every symbol of the module from BPF and
depends on module internals with no stable layout.
- Reading /proc/kallsyms before the init function returns, which is a
race userspace usually loses.
bpf_snprintf() was added in Linux 5.13, so this raises the minimum
kernel from 5.8 (BPF ring buffer) to 5.13.
Fixes #8
The stack traces now resolve the module's __init function and show the current kernel's allocation path, and the verbose output no longer mentions the renamed validate_stack program.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.