Ich glaube, dass das Anhängen von eBPF an kprobes/kretprobes Ihnen Lesezugriff auf Funktionsargumente und Rückgabewerte gibt, aber dass Sie sie nicht manipulieren können. Ich bin mir NICHT 100% sicher; gute Orte, um eine Bestätigung zu erbitten, sind die Mailingliste des IO Visor-Projekts oder der IRC-Kanal (#iovisor at irc.oftc.net).
Als alternative Lösung weiß ich, dass Sie zumindest den Rückgabewert eines Systemaufrufs mit strace ändern können, mit dem -e
Möglichkeit. Zitieren der Handbuchseite:
-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr] Perform syscall tampering for the specified set of syscalls.
Außerdem gab es auf der Fosdem 2017 eine Präsentation dazu und zur Fehlerinjektion, falls es für Sie von Interesse ist. Hier ist ein Beispielbefehl aus den Folien:
strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt
Bearbeiten: Wie von Ben angegeben, ist eBPF auf kprobes und Tracepoints definitiv schreibgeschützt, um Anwendungsfälle zu verfolgen und zu überwachen. Ich habe auch eine Bestätigung darüber im IRC bekommen.
Innerhalb von Kernel-Probes (kprobes) hat die virtuelle eBPF-Maschine schreibgeschützten Zugriff auf die Syscall-Parameter und den Rückgabewert.
Das eBPF-Programm hat jedoch einen eigenen Rückkehrcode. Es ist möglich, ein seccomp-Profil anzuwenden, das BPF-Rückgabecodes (NICHT eBPF; danke @qeole) abfängt und den Systemaufruf während der Ausführung unterbricht.
Die erlaubten Laufzeitänderungen sind:
SECCOMP_RET_KILL
:Sofortiger Kill mitSIGSYS
SECCOMP_RET_TRAP
:Senden Sie einen abfangbarenSIGSYS
, um den Systemaufruf zu emulierenSECCOMP_RET_ERRNO
:errno
erzwingen WertSECCOMP_RET_TRACE
:Entscheidung an Ptracer übergeben odererrno
setzen bis-ENOSYS
SECCOMP_RET_ALLOW
:Zulassen
https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
Die SECCOMP_RET_TRACE
-Methode ermöglicht das Ändern des durchgeführten Systemaufrufs, der Argumente oder des Rückgabewerts. Dies ist architekturabhängig und die Änderung obligatorischer externer Referenzen kann einen ENOSYS-Fehler verursachen.
Dazu wird die Ausführung an einen wartenden Userspace-Ptrace übergeben, der die Fähigkeit hat, den verfolgten Prozessspeicher, die Register und die Dateideskriptoren zu ändern.
Der Tracer muss ptrace und dann waitpid aufrufen. Ein Beispiel:
ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP);
waitpid(tracee_pid, &status, 0);
http://man7.org/linux/man-pages/man2/ptrace.2.html
Wenn waitpid
zurück, abhängig vom Inhalt von status
, kann man den seccomp-Rückgabewert mit PTRACE_GETEVENTMSG
abrufen ptrace-Operation. Dadurch wird der seccomp SECCOMP_RET_DATA
abgerufen Wert, der ein 16-Bit-Feld ist, das vom BPF-Programm gesetzt wird. Beispiel:
ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);
Syscall-Argumente können im Speicher geändert werden, bevor der Betrieb fortgesetzt wird. Mit PTRACE_SYSCALL
können Sie einen einzelnen Syscall-Einstieg oder -Ausstieg durchführen Schritt. Syscall-Rückgabewerte können im Userspace geändert werden, bevor die Ausführung fortgesetzt wird; das zugrunde liegende Programm kann nicht sehen, dass die Systemaufruf-Rückgabewerte geändert wurden.
Eine Beispielimplementierung:Systemaufrufe mit seccomp und ptrace filtern und modifizieren