Skip to content
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

Implement override_return #966

Merged
merged 3 commits into from
Jan 22, 2020
Merged

Implement override_return #966

merged 3 commits into from
Jan 22, 2020

Conversation

fbs
Copy link
Contributor

@fbs fbs commented Nov 12, 2019

The implementation of this turned out quite straight forward.

I've chosen to skip testing whether the probed function can actually be overridden (using /sys/kernel/debug/error_injection/list) as I didn't see that much value in it. It is not a function that will be used often and the people that do use it are probably aware of the limitations. If someone has a strong opinion about it I'll happily implement it however.

This helper is not yet available in the CI so I've skipped the runtime tests.

Example:

$ sudo bpftrace -e 'k:__x64_sys_getuid /comm == "id"/ { override_return(2<<21); }' --unsafe -c id
Attaching 1 probe...
uid=4194304 gid=0(root) euid=0(root) groups=0(root)

Fixes #720

@fbs fbs force-pushed the 720_override_return branch 3 times, most recently from 78a57a1 to 3c292be Compare November 13, 2019 22:11
@@ -681,7 +681,19 @@ void CodegenLLVM::visit(Call &call)
}
expr_ = stackid;
}

else if (call.func == "override_return") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move the { onto a separate line to match the surrounding code please? (here and below)
Nitpicky, but I think I might go through and reformat all the code one day to be consistent so I'm trying to minimise my future changes ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do, I always mess it up. Would be good to get #639 done :)

src/ast/codegen_llvm.cpp Outdated Show resolved Hide resolved
@@ -47,6 +47,9 @@ add_executable(bpftrace_test
${CMAKE_SOURCE_DIR}/src/types.cpp
${CMAKE_SOURCE_DIR}/src/utils.cpp
${CMAKE_SOURCE_DIR}/src/disasm.cpp
${CMAKE_SOURCE_DIR}/src/ast/semantic_analyser.cpp
${CMAKE_SOURCE_DIR}/src/ast/codegen_llvm.cpp
${CMAKE_SOURCE_DIR}/src/ast/irbuilderbpf.cpp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're already doing target_link_libraries(bpftrace_test ast) - doesn't that cover what we need without this change?

Copy link
Contributor Author

@fbs fbs Nov 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted the semantic and codegen tests to always run, regardless of whether the kernel supports override_return or not.

The way cgroupid solves that is by putting the #ifdef in the codegen, but then you loose the option to fail nicely (with line number and source code) and instead have to abort out, and you cannot test codegen.

The "hack" I did here is to always define HAVE_OVERRIDE_RETURN in the test suite, regardless whether the kernel supports it. And define BPF_FUNC_override_return when it is not supported by the system. As those flags are used in the semantic and codegen phases those have to be recompiled for the tests but not the actual bpftrace build.

This hack got already merged in with the merge of signal but I'll happily fix that if we can find a better way to do this. I'm not entirely happy with it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I can't think of a better way

tests/CMakeLists.txt Outdated Show resolved Hide resolved
@fbs fbs force-pushed the 720_override_return branch 2 times, most recently from 7cb8cec to c75aea1 Compare November 25, 2019 08:55
@fbs
Copy link
Contributor Author

fbs commented Nov 25, 2019

Fix the comments @ajor, thanks!

#966 (comment) got a bit hidden now but it is still relevant.

Copy link
Member

@ajor ajor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, looks good to me!

@fbs fbs force-pushed the 720_override_return branch 4 times, most recently from a94c859 to b90494a Compare December 29, 2019 00:48
This allows the user to modify the return value for a kprobe. It's use
is quite limited as the kernel puts heavy restrictions on it:

> This helper has security implications, and thus is subject to
> restrictions. It is only available if the kernel was compiled
> with the **CONFIG_BPF_KPROBE_OVERRIDE** configuration
> option, and in this case it only works on functions tagged with
> **ALLOW_ERROR_INJECTION** in the kernel code.
>
> Also, the helper is only available for the architectures having
> the CONFIG_FUNCTION_ERROR_INJECTION option. As of this writing,
> x86 architecture is the only one to support this feature.

Example usage:

```
bpftrace -e 'k:__x64_sys_openat /comm == "cat"/ { override_return(-4); }'

cat lex.yy.cc
cat: error while loading shared libraries: libc.so.6: cannot open shared object file: Error 4
```
A badly inserted override has the possibility to break your system. One
such example is `kprobe:do_openat { override_return(-1); }` which will
prevent your whole system from opening files.
@fbs
Copy link
Contributor Author

fbs commented Jan 21, 2020

I've rebased it onto master, the feature detecting should solve all CI issues it had.

@ajor ajor merged commit b83b51d into bpftrace:master Jan 22, 2020
@brendangregg
Copy link
Contributor

brendangregg commented Jan 22, 2020

Sorry for the late comment: did we want it named override_return()? It's a long function name and includes an underscore, and doesn't sound like the other bpftrace functions (printf(), ksym(), str(), etc). What about just override() or return()?

@fbs fbs deleted the 720_override_return branch January 22, 2020 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add support for bpf_override_return()
3 participants