Je pense qu'attacher eBPF à kprobes/kretprobes vous donne un accès en lecture aux arguments de fonction et aux valeurs de retour, mais que vous ne pouvez pas les altérer. Je ne suis PAS sûr à 100 % ; les bons endroits pour demander une confirmation seraient la liste de diffusion du projet IO Visor ou le canal IRC (#iovisor sur irc.oftc.net).
Comme solution alternative, je sais que vous pouvez au moins changer la valeur de retour d'un appel système avec strace, avec le -e
option. Citant la page de manuel :
-e inject=set[:error=errno|:retval=value][:signal=sig][:when=expr] Perform syscall tampering for the specified set of syscalls.
De plus, il y a eu une présentation à ce sujet, et l'injection de fautes, à Fosdem 2017, si cela vous intéresse. Voici un exemple de commande des diapositives :
strace -P precious.txt -efault=unlink:retval=0 unlink precious.txt
Modifier : Comme l'a déclaré Ben, eBPF sur les kprobes et les points de trace est définitivement en lecture seule, pour le traçage et la surveillance des cas d'utilisation. J'ai également reçu une confirmation à ce sujet sur IRC.
Dans les sondes du noyau (kprobes), la machine virtuelle eBPF a un accès en lecture seule aux paramètres d'appel système et à la valeur de retour.
Cependant, le programme eBPF aura son propre code de retour. Il est possible d'appliquer un profil seccomp qui piège les codes de retour BPF (PAS eBPF ; merci @qeole) et interrompt l'appel système pendant l'exécution.
Les modifications d'exécution autorisées sont :
SECCOMP_RET_KILL
:Tuer immédiatement avecSIGSYS
SECCOMP_RET_TRAP
:Envoie unSIGSYS
attrapable , permettant d'émuler l'appel systèmeSECCOMP_RET_ERRNO
:Forcererrno
valeurSECCOMP_RET_TRACE
:Rendre la décision à ptracer ou définirerrno
à-ENOSYS
SECCOMP_RET_ALLOW
:Autoriser
https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
Le SECCOMP_RET_TRACE
La méthode permet de modifier l'appel système effectué, les arguments ou la valeur de retour. Cela dépend de l'architecture et la modification des références externes obligatoires peut provoquer une erreur ENOSYS.
Pour ce faire, il transmet l'exécution à un ptrace de l'espace utilisateur en attente, qui a la capacité de modifier la mémoire, les registres et les descripteurs de fichiers du processus tracé.
Le traceur doit appeler ptrace puis waitpid. Un exemple :
ptrace(PTRACE_SETOPTIONS, tracee_pid, 0, PTRACE_O_TRACESECCOMP);
waitpid(tracee_pid, &status, 0);
http://man7.org/linux/man-pages/man2/ptrace.2.html
Quand waitpid
renvoie, selon le contenu de status
, on peut récupérer la valeur de retour seccomp en utilisant le PTRACE_GETEVENTMSG
opération ptrace. Cela récupérera le seccomp SECCOMP_RET_DATA
valeur, qui est un champ de 16 bits défini par le programme BPF. Exemple :
ptrace(PTRACE_GETEVENTMSG, tracee_pid, 0, &data);
Les arguments syscall peuvent être modifiés en mémoire avant de poursuivre l'opération. Vous pouvez effectuer une seule entrée ou sortie d'appel système avec le PTRACE_SYSCALL
marcher. Les valeurs de retour des appels système peuvent être modifiées dans l'espace utilisateur avant de reprendre l'exécution ; le programme sous-jacent ne pourra pas voir que les valeurs de retour syscall ont été modifiées.
Un exemple d'implémentation :filtrer et modifier les appels système avec seccomp et ptrace