Can eBPF change the return value or system call parameters?

In order to simulate some kind of behavior, I would like to bind the probe to syscall and change the return value when certain parameters are passed. Alternatively, it would also be sufficient to change the function parameters before they become processes.

Is this possible with BPF?


source to share

2 answers

I suppose binding eBPF to kprobes / kretprobes gives you access to function arguments and return values, but you cannot tamper with them. I am NOT 100% sure; Good places to request confirmation would be the IO Visor project mailing list or IRC channel (#iovisor at

As an alternative solution, I know that you can at least change the return value of syscall with strace with -e

. Quoting the man page :

-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr]
       Perform syscall tampering for the specified set of syscalls.


In addition, there was a presentation about this and the error injection in Fosdem 2017 if that interests you. Here's an example of a command from the slides:

strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt


Edit: As Ben stated, the eBPF on kprobes and checkpoints is definitively readable only for tracking and monitoring use cases. I also got confirmation on this on IRC.



Inside the kernel probes (kprobes), the eBPF virtual machine has read-only access to the syscall parameters and return value.

However, the eBPF program will have its own return code. You can use the seccomp profile, which intercepts BPF (NOT eBPF; thanks @qeole) return codes and aborts the system call at runtime.

Allowed runtime modifications:


    : Immediate destruction with SIGSYS


    : SIGSYS

    post an exciting , emulating syscall

    : Force value errno


    : output solution for ptracer or install errno



    : Allow


allows you to change the system call being executed, the arguments, or the return value. This is architecture dependent and changing required xrefs may result in an ENOSYS error.

It does this by passing execution to the pending user ptrace, which has the ability to modify the process's monitored memory, registers, and file descriptors.

The tracer needs to call ptrace and then waitpid. Example:

waitpid(tracee_pid, &status, 0);

When waitpid

returned, depending on the content status

, you can return the return value of seccomp using the PTRACE_GETEVENTMSG

ptrace operation . This will return the seccomp value SECCOMP_RET_DATA

, which is a 16-bit field specified by the BPF program. Example:

ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);


Syscall parameters can be changed in memory before continuing. You can do a single write or log out with syscall in steps PTRACE_SYSCALL

. Syscall return values ​​can be changed in user space before resuming execution; the main program will not be able to see that the syscall return values ​​have changed.

Example implementation: Filter and modify system calls with seccomp and ptrace



All Articles