New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support to attach kprobe to offset #956
Conversation
So kernel image is needed to test. Although it does not need to be a debug symbol... (it takes too much time to fetch.) |
It seems we can use extract-vmlinux. vmlinux is stripped, so we need to consult /boot/System.map to disassemble. |
Ah, I just realized that kprobe checks instruction boundaries when registering (src). I'm wondering userspace check is needed. |
The link you posted is for the ftrace interface (/sys/kernel/debug/tracing). bpftrace uses the perf interface. That being said, it looks like the same checks are done in the perf code paths. Can you do some tests to see if -EILSEQ is returned from |
Thanks for the review. I'll fix these points. I confirmed that So, if bpftrace does not perform a boundary check and tries to attach kprobe to an invalid offset, the output looks like:
"cannot attach kprobe, Invalid ..." is a message from bcc. One of the downsides of relying on kernel boundary checks is that it does not check whether the offset is within a function. For example, the following will work in my environment.
But if bpftrace checks boundary using vmlinux, it fails.
I'm thinking of the following:
|
9e32ec5
to
e344595
Compare
I made the following changes:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the delay. Everything LGTM. Just some small comments and the merge conflict.
src/attached_probe.cpp
Outdated
// based on btf_location in btf.cpp | ||
const char *vmlinux_locs[] = { | ||
"/boot/vmlinux-%1$s", | ||
"/lib/modules/%1$s/vmlinux-%1$s", | ||
"/lib/modules/%1$s/build/vmlinux", | ||
"/usr/lib/modules/%1$s/kernel/vmlinux", | ||
"/usr/lib/debug/boot/vmlinux-%1$s", | ||
"/usr/lib/debug/boot/vmlinux-%1$s.debug", | ||
"/usr/lib/debug/lib/modules/%1$s/vmlinux", | ||
nullptr, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this list to utils.cpp and have btf.cpp use it too? Would be nice to maintain it in one location
Example: `bpftrace -e 'kprobe:do_sys_open+9 { ... }'`. This is based on the support of attaching uprobe to offset (bpftrace#803). The offset is checked whether it is an instruction boundary using vmlinux (with debug symbols). The environment variable `BPFTRACE_VMLINUX` can be used to specify vmlinux file. ALLOW_UNSAFE_UPROBE option is renamed to ALLOW_UNSASFE_PROBE so that it supports both uprobe and kprobe. If bpftrace is compoiled with ALLOW_UNSASFE_PROBE option and vmlinux file is not found, and --unsafe option is given, the userspace check is skipped. Note that linux kernel checks the address alignment, but it does not check whether it is within the function. Closes bpftrace#42
e344595
to
e348ede
Compare
This test requires vmlinux with debug symbols. It is possible to download it in CI, but it takes time (6~7 mins).
vmlinux is used for both symbol resolution and BTF. Manage the location list in one place.
e348ede
to
d58bf05
Compare
@danobi |
Is there anything wrong with not checking the function boundary? What does "unsafe" mean here? As far as I know BPF is always "safe" in that nothing we run in it can take down the kernel. |
Indeed, I believe not checking the boundary is totally safe in that sense. The checking just prevents us from some coding errors. Once again, I'm wondering userspace check is needed. Having the functionality of reading vmlinux may be useful in the future though (e.g., perf-probe analyze DWARF symbols and can show information on local variable locations.) |
I guess we don't have to check boundaries in userspace. But IMO it's a nice check to prevent some unintended bugs. We can always relax these checks without breaking API but adding them in later will break API. I don't feel too strongly either way. If it's not too much of runtime overhead I'd lean towards leaving userspace checks in. |
In addition, "--unsafe" here means skipping user checking and this is the same as the option for uprobe. It is possible to attach uprobe to the middle of instructions, so it is "unsafe". On the other hand, in the case of kprobe, kernel does minimum safety checks. |
Let's merge this for now. If we run into issues or change our minds, the door is always open to take out userspace checks. |
Example:
bpftrace -e 'kprobe:do_sys_open+9 { ... }'
.This is based on the support of attaching uprobe to offset (#803). The
offset is checked whether it is an instruction boundary using vmlinux.
The environment variable
BPFTRACE_VMLINUX
can be used to specifyvmlinux file. ALLOW_UNSAFE_UPROBE option is renamed to
ALLOW_UNSASFE_PROBE so that it supports both uprobe and kprobe.
Closes #42