Skip to content

Commit 316cba6

Browse files
olsajiriborkmann
authored andcommitted
bpf, x64: Allow to use caller address from stack
Currently we call the original function by using the absolute address given at the JIT generation. That's not usable when having trampoline attached to multiple functions, or the target address changes dynamically (in case of live patch). In such cases we need to take the return address from the stack. Adding support to retrieve the original function address from the stack by adding new BPF_TRAMP_F_ORIG_STACK flag for arch_prepare_bpf_trampoline function. Basically we take the return address of the 'fentry' call: function + 0: call fentry # stores 'function + 5' address on stack function + 5: ... The 'function + 5' address will be used as the address for the original function to call. Signed-off-by: Jiri Olsa <[email protected]> Signed-off-by: Song Liu <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 53cd885 commit 316cba6

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

arch/x86/net/bpf_jit_comp.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2119,10 +2119,15 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
21192119
if (flags & BPF_TRAMP_F_CALL_ORIG) {
21202120
restore_regs(m, &prog, nr_args, regs_off);
21212121

2122-
/* call original function */
2123-
if (emit_call(&prog, orig_call, prog)) {
2124-
ret = -EINVAL;
2125-
goto cleanup;
2122+
if (flags & BPF_TRAMP_F_ORIG_STACK) {
2123+
emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8);
2124+
EMIT2(0xff, 0xd0); /* call *rax */
2125+
} else {
2126+
/* call original function */
2127+
if (emit_call(&prog, orig_call, prog)) {
2128+
ret = -EINVAL;
2129+
goto cleanup;
2130+
}
21262131
}
21272132
/* remember return value in a stack for bpf prog to access */
21282133
emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8);

include/linux/bpf.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,11 @@ struct btf_func_model {
751751
/* Return the return value of fentry prog. Only used by bpf_struct_ops. */
752752
#define BPF_TRAMP_F_RET_FENTRY_RET BIT(4)
753753

754+
/* Get original function from stack instead of from provided direct address.
755+
* Makes sense for trampolines with fexit or fmod_ret programs.
756+
*/
757+
#define BPF_TRAMP_F_ORIG_STACK BIT(5)
758+
754759
/* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50
755760
* bytes on x86.
756761
*/

0 commit comments

Comments
 (0)