.\" -*- coding: UTF-8 -*- .\" Copyright (c) 1993 Michael Haardt .\" Fri Apr 2 11:32:09 MET DST 1993 .\" .\" and changes Copyright (C) 1999 Mike Coleman (mkc@acm.org) .\" -- major revision to fully document ptrace semantics per recent Linux .\" kernel (2.2.10) and glibc (2.1.2) .\" Sun Nov 7 03:18:35 CST 1999 .\" .\" and Copyright (c) 2011, Denys Vlasenko .\" and Copyright (c) 2015, 2016, Michael Kerrisk .\" .\" SPDX-License-Identifier: GPL-2.0-or-later .\" .\" Modified Fri Jul 23 23:47:18 1993 by Rik Faith .\" Modified Fri Jan 31 16:46:30 1997 by Eric S. Raymond .\" Modified Thu Oct 7 17:28:49 1999 by Andries Brouwer .\" Modified, 27 May 2004, Michael Kerrisk .\" Added notes on capability requirements .\" .\" 2006-03-24, Chuck Ebbert <76306.1226@compuserve.com> .\" Added PTRACE_SETOPTIONS, PTRACE_GETEVENTMSG, PTRACE_GETSIGINFO, .\" PTRACE_SETSIGINFO, PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP .\" (Thanks to Blaisorblade, Daniel Jacobowitz and others who helped.) .\" 2011-09, major update by Denys Vlasenko .\" 2015-01, Kees Cook .\" Added PTRACE_O_TRACESECCOMP, PTRACE_EVENT_SECCOMP .\" .\" FIXME The following are undocumented: .\" .\" PTRACE_GETWMMXREGS .\" PTRACE_SETWMMXREGS .\" ARM .\" Linux 2.6.12 .\" .\" PTRACE_SET_SYSCALL .\" ARM and ARM64 .\" Linux 2.6.16 .\" commit 3f471126ee53feb5e9b210ea2f525ed3bb9b7a7f .\" Author: Nicolas Pitre .\" Date: Sat Jan 14 19:30:04 2006 +0000 .\" .\" PTRACE_GETCRUNCHREGS .\" PTRACE_SETCRUNCHREGS .\" ARM .\" Linux 2.6.18 .\" commit 3bec6ded282b331552587267d67a06ed7fd95ddd .\" Author: Lennert Buytenhek .\" Date: Tue Jun 27 22:56:18 2006 +0100 .\" .\" PTRACE_GETVFPREGS .\" PTRACE_SETVFPREGS .\" ARM and ARM64 .\" Linux 2.6.30 .\" commit 3d1228ead618b88e8606015cbabc49019981805d .\" Author: Catalin Marinas .\" Date: Wed Feb 11 13:12:56 2009 +0100 .\" .\" PTRACE_GETHBPREGS .\" PTRACE_SETHBPREGS .\" ARM and ARM64 .\" Linux 2.6.37 .\" commit 864232fa1a2f8dfe003438ef0851a56722740f3e .\" Author: Will Deacon .\" Date: Fri Sep 3 10:42:55 2010 +0100 .\" .\" PTRACE_SINGLEBLOCK .\" Since at least Linux 2.4.0 on various architectures .\" Since Linux 2.6.25 on x86 (and others?) .\" commit 5b88abbf770a0e1975c668743100f42934f385e8 .\" Author: Roland McGrath .\" Date: Wed Jan 30 13:30:53 2008 +0100 .\" ptrace: generic PTRACE_SINGLEBLOCK .\" .\" PTRACE_GETFPXREGS .\" PTRACE_SETFPXREGS .\" Since at least Linux 2.4.0 on various architectures .\" .\" PTRACE_GETFDPIC .\" PTRACE_GETFDPIC_EXEC .\" PTRACE_GETFDPIC_INTERP .\" blackfin, c6x, frv, sh .\" First appearance in Linux 2.6.11 on frv .\" .\" and others that can be found in the arch/*/include/uapi/asm/ptrace files .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH ptrace 2 "30 mars 2023" "Pages du manuel de Linux 6.05.01" .SH NOM ptrace \- Suivre un processus .SH BIBLIOTHÈQUE Bibliothèque C standard (\fIlibc\fP, \fI\-lc\fP) .SH SYNOPSIS .nf \fB#include \fP .PP \fBlong ptrace(enum __ptrace_request \fP\fIrequest\fP\fB, pid_t \fP\fIpid\fP\fB,\fP \fB void *\fP\fIaddr\fP\fB, void *\fP\fIdata\fP\fB);\fP .fi .SH DESCRIPTION L'appel système \fBptrace\fP() fournit à un processus (l'«\ observateur\ ») un moyen d'observer et de contrôler l'exécution d'un autre processus (l'«\ observé\ »), et d'examiner et éditer la mémoire et les registres de l'observé. L'utilisation principale de cette fonction est l'implémentation de points d'arrêt pour le débogage, et pour suivre les appels système. .PP Un observé doit d'abord être attaché à l'observateur. L'attachement et les commandes suivantes sont par thread\ : dans un processus multithreadé, chaque thread peut être attaché individuellement à un observateur (éventuellement différent), ou être laissé détaché et donc non débogué. Par conséquent, l'«\ observé\ » signifie toujours «\ (un) thread\ », jamais «\ un processus (éventuellement multithreadé)\ ». Les commandes ptrace sont toujours envoyées à un observé spécifique en utilisant un appel de la forme .PP .in +4n .EX ptrace(PTRACE_truc, pid, ...) .EE .in .PP où \fIpid\fP est l'identifiant de thread du thread Linux correspondant. .PP (Remarquez que dans cette page, un «\ processus multithreadé\ » signifie un groupe de threads constitué de threads créés en utilisant l'attribut \fBCLONE_THREAD\fP de \fBclone\fP(2).) .PP Un processus peut démarrer un suivi en appelant \fBfork\fP(2) et faire en sorte que l'enfant créé fasse un \fBPTRACE_TRACEME\fP, suivi (en général) par un \fBexecve\fP(2). Autrement, un processus peut commencer à suivre un autre processus en utilisant \fBPTRACE_ATTACH\fP ou \fBPTRACE_SEIZE\fP. .PP L'observé s'arrêtera à chaque fois qu'un signal lui sera distribué, même si le signal est ignoré (à l'exception de \fBSIGKILL\fP qui a les effets habituels). L'observateur sera prévenu à son prochain appel de \fBwaitpid\fP(2) (ou un des appels système liés à «\ wait\ »)\ ; cet appel renverra une valeur \fIstatus\fP contenant les renseignements indiquant la raison de l'arrêt de l'observé. Lorsque l'observé est arrêté, l'observateur peut utiliser plusieurs requêtes ptrace pour inspecter et modifier l'observé. L'observateur peut également laisser continuer l'exécution de l'observé, en ignorant éventuellement le signal ayant déclenché l'arrêt, ou même en envoyant un autre signal. .PP Si l'option \fBPTRACE_O_TRACEEXEC\fP n'est pas effective, tous les appels réussis d'\fBexecve\fP(2) par le processus suivi déclencheront l'envoi d'un signal \fBSIGTRAP\fP, ce qui permet au parent de reprendre le contrôle avant que le nouveau programme commence son exécution. .PP Quand l'observateur a fini le suivi, il peut forcer l'observé à continuer normalement, en mode non suivi, avec \fBPTRACE_DETACH\fP. .PP La valeur de l'argument \fIrequest\fP indique précisément l'action à entreprendre. .TP \fBPTRACE_TRACEME\fP Le processus en cours va être suivi par son parent. Un processus ne devrait sans doute pas envoyer cette requête si son parent n'est pas prêt à le suivre. Dans cette requête \fIpid\fP, \fIaddr\fP, et \fIdata\fP sont ignorés. .IP La requête \fBPTRACE_TRACEME\fP ne sert qu'à l'observé. Les requêtes restantes ne servent qu'à l'observateur. Par la suite, \fIpid\fP précise l'identifiant de thread de l'observé sur lequel agir. Pour d'autres requêtes que \fBPTRACE_ATTACH\fP, \fBPTRACE_SEIZE\fP, \fBPTRACE_INTERRUPT\fP et \fBPTRACE_KILL\fP, l'observé doit être arrêté. .TP \fBPTRACE_PEEKTEXT\fP, \fBPTRACE_PEEKDATA\fP Lire un mot à l'adresse \fIaddr\fP dans l'espace mémoire de l'observé et le renvoyer en résultat de l'appel \fBptrace\fP(). Linux ne sépare pas les espaces d'adressage de code et de données, donc ces deux requêtes sont équivalentes (\fIdata\fP est ignoré, consultez la section NOTES). .TP \fBPTRACE_PEEKUSER\fP .\" PTRACE_PEEKUSR in kernel source, but glibc uses PTRACE_PEEKUSER, .\" and that is the name that seems common on other systems. Lire un mot à la position \fIaddr\fP dans l'espace USER de l'observé, qui contient les registres et divers renseignements sur le processus (voir \fI\fP). Le mot est renvoyée en résultat de \fBptrace\fP(). En principe, l'adresse doit être alignée sur une frontière de mots, bien que cela varie selon les architectures. Consultez la section \fBNOTES\fP. (\fIdata\fP est ignoré, consultez la section \fBNOTES\fP). .TP \fBPTRACE_POKETEXT\fP, \fBPTRACE_POKEDATA\fP Copier le mot \fIdata\fP vers l'adresse \fIaddr\fP de la mémoire de l'observé. Comme pour \fBPTRACE_PEEKTEXT\fP et \fBPTRACE_PEEKDATA\fP, ces deux requêtes sont équivalentes. .TP \fBPTRACE_POKEUSER\fP .\" PTRACE_POKEUSR in kernel source, but glibc uses PTRACE_POKEUSER, .\" and that is the name that seems common on other systems. .\" FIXME In the preceding sentence, which modifications are disallowed, .\" and when they are disallowed, how does user space discover that fact? Copier le mot \fIdata\fP vers l'adresse \fIaddr\fP dans l'espace USER de l'observé. Comme pour \fBPTRACE_PEEKUSER\fP, les emplacements doivent être alignés sur une frontière de mot. Pour maintenir l'intégrité du noyau, certaines modifications de la zone USER sont interdites. .TP \fBPTRACE_GETREGS\fP, \fBPTRACE_GETFPREGS\fP Copier les registres généraux ou du processeur en virgule flottante de l'observé, vers l'adresse \fIdata\fP de l'observateur. Consultez \fI\fP pour les détails sur le format de ces données (\fIaddr\fP est ignoré). Remarquez que les systèmes SPARC ont la signification de \fIdata\fP et \fIaddr\fP inversée, c'est\-à\-dire que \fIdata\fP est ignoré et les registres sont copiés vers l'adresse \fIaddr\fP. \fBPTRACE_GETREGS\fP et \fBPTRACE_GETFPREGS\fP ne sont pas présents sur toutes les architectures. .TP \fBPTRACE_GETREGSET\fP (depuis Linux\ 2.6.34) Lire les registres de l'observé. \fIaddr\fP indique, de manière dépendante de l'architecture, le type de registres à lire. \fBNT_PRSTATUS\fP (avec une valeur numérique de 1) a pour conséquence habituelle la lecture de registres généraux. Si le processeur a, par exemple, des registres en virgule flottante ou en vecteur, ils peuvent être récupéré en configurant \fIaddr\fP à la constante \fBNT_foo\fP correspondante. \fIdata\fP pointe vers une \fBstruct iovec\fP, qui décrit l'emplacement et la taille du tampon de destination. Le noyau modifie \fBiov.len\fP au retour pour indiquer le véritable nombre d'octets renvoyés. .TP \fBPTRACE_SETREGS\fP, \fBPTRACE_SETFPREGS\fP .\" FIXME . In the preceding sentence, which modifications are disallowed, .\" and when they are disallowed, how does user space discover that fact? Modifier les registres généraux ou du processeur en virgule flottante de l'observé, depuis l'adresse \fIdata\fP de l'observateur. Comme pour \fBPTRACE_POKEUSER\fP, certaines modifications de registres généraux pourraient être interdites (\fIaddr\fP est ignoré). Remarquez que les systèmes SPARC ont la signification de \fIdata\fP et \fIaddr\fP inversée, c'est\-à\-dire que \fIdata\fP est ignoré et les registres sont copiés depuis l'adresse \fIaddr\fP. \fBPTRACE_SETREGS\fP\ et \fBPTRACE_SETFPREGS\fP ne sont pas présents sur toutes les architectures. .TP \fBPTRACE_SETREGSET\fP (depuis Linux\ 2.6.34) Modifier les registres de l'observé. La signification de \fIaddr\fP et \fIdata\fP est analogue à \fBPTRACE_GETREGSET\fP. .TP \fBPTRACE_GETSIGINFO\fP (depuis Linux\ 2.3.99\-pre6) Récupérer des renseignements sur le signal qui a provoqué l'arrêt. Pour ce faire, copier une structure \fIsiginfo_t\fP (consultez \fBsigaction\fP(2)) de l'observé à l'adresse \fIdata\fP de l'observateur (\fIaddr\fP est ignoré). .TP \fBPTRACE_SETSIGINFO\fP (depuis Linux\ 2.3.99\-pre6) Définir les renseignements de signaux\ : copier une structure \fIsiginfo_t\fP de l'adresse \fIdata\fP de l'observateur vers l'observé. Cela n'affecte que les signaux qui auraient dû être distribués à l'observé et ont été interceptés à cause de \fBptrace\fP(). Différencier ces signaux normaux des signaux créés par \fBptrace\fP() lui\-même peut être délicat (\fIaddr\fP est ignoré). .TP \fBPTRACE_PEEKSIGINFO\fP (depuis Linux\ 3.10) .\" commit 84c751bd4aebbaae995fe32279d3dba48327bad4 Récupérer les structures \fIsiginfo_t\fP sans supprimer les signaux d’une file d’attente. \fIaddr\fP pointe vers une structure \fIptrace_peeksiginfo_args\fP qui indique la position ordinale à partir de laquelle la copie des signaux devrait commencer et le nombre de signaux à copier. Les structures \fIsiginfo_t\fP sont copiées dans le tampon pointé par \fIdata\fP. La valeur de retour contient le nombre de signaux copiés (zéro indique qu’il n’y a pas de signal correspondant à la position ordinale indiquée). Dans les structures \fIsiginfo\fP renvoyées, le champ \fIsi_code\fP contient des renseignements (\fB__SI_CHLD\fP, \fB__SI_FAULT\fP,\ etc.) qui sinon ne sont pas exposés à l’espace utilisateur. .PP .in +4n .EX struct ptrace_peeksiginfo_args { u64 off; /* Position ordinale dans la file d’attente où commencer la copie de signaux */ u32 flags; /* PTRACE_PEEKSIGINFO_SHARED ou 0 */ s32 nr; /* Nombre de signaux à copier */ }; .EE .in .IP Actuellement, seul l’attribut \fBPTRACE_PEEKSIGINFO_SHARED\fP permet de vider les signaux de la file de signaux par processus. Si cet attribut n’est pas défini, les signaux sont lus depuis la file par thread du thread indiqué. .in .TP \fBPTRACE_GETSIGMASK\fP (depuis Linux\ 3.11) .\" commit 29000caecbe87b6b66f144f72111f0d02fbbf0c1 Placer une copie du masque des signaux bloqués (consultez \fBsigprocmask\fP(2)) dans le tampon pointé par \fIdata\fP qui devrait être un pointeur vers un tampon de type \fIsigset_t\fP. L’argument \fIaddr\fP contient la taille du tampon pointé par \fIdata\fP (c’est\-à\-dire \fIsizeof(sigset_t)\fP). .TP \fBPTRACE_SETSIGMASK\fP (depuis Linux\ 3.11) Modifier le masque des signaux bloqués (consultez \fBsigprocmask\fP(2)) à la valeur indiquée dans le tampon pointé par \fIdata\fP qui devrait être un pointeur vers un tampon de type \fIsigset_t\fP. L’argument \fIaddr\fP contient la taille du tampon pointé par \fIdata\fP (c’est\-à\-dire \fIsizeof(sigset_t)\fP). .TP \fBPTRACE_SETOPTIONS\fP (depuis Linux\ 2.4.6, consultez les remarques de \fBBOGUES\fP) Définir les options de ptrace à partir de l'adresse \fIdata\fP (\fIaddr\fP est ignoré). \fIdata\fP est interprété comme un masque d'options, qui est construit à partir des attributs suivants. .RS .TP \fBPTRACE_O_EXITKILL\fP (depuis Linux\ 3.8) .\" commit 992fb6e170639b0849bace8e49bf31bd37c4123 Envoyer un signal \fBSIGKILL\fP à l'observé si l'observateur existe. Cet option est utile pour les gardiens ptrace qui veulent s'assurer que les observés ne peuvent jamais échapper au contrôle de l'observateur. .TP \fBPTRACE_O_TRACECLONE\fP (depuis Linux\ 2.5.46) Arrêter l'observé au prochain \fBclone\fP(2) et commencer automatiquement à suivre le nouveau processus cloné, qui démarrera avec un signal \fBSIGSTOP\fP, ou \fBPTRACE_EVENT_STOP\fP si \fBPTRACE_SEIZE\fP est utilisé. Un \fBwaitpid\fP(2) par l'observateur renverra une valeur \fIstatus\fP comme .IP .nf status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8)) .fi .IP Le PID du nouveau processus peut être récupéré avec \fBPTRACE_GETEVENTMSG\fP. .IP Cette option peut ne pas intercepter tous les appels \fBclone\fP(2). Si l'observé appelle \fBclone\fP(2) avec l'attribut \fBCLONE_VFORK\fP, \fBPTRACE_EVENT_VFORK\fP sera envoyé si \fBPTRACE_O_TRACEVFORK\fP est utilisé. Sinon, si l'observé appelle \fBclone\fP(2) avec \fBSIGCHLD\fP comme signal de terminaison, \fBPTRACE_EVENT_FORK\fP sera envoyé si \fBPTRACE_O_TRACEFORK\fP est utilisé. .TP \fBPTRACE_O_TRACEEXEC\fP (depuis Linux\ 2.5.46) Arrêter l'observé au prochain \fBexecve\fP(2). Un \fBwaitpid\fP(2) par l'observateur renverra une valeur \fIstatus\fP comme .IP .nf status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8)) .fi .IP Si le thread en cours d'exécution n'est pas un leader de groupe de threads, l'identifiant de thread est réinitialisé à l'identifiant du leader de groupe de threads avant cet arrêt. Depuis Linux\ 3.0, le premier identifiant de thread peut être récupéré avec \fBPTRACE_GETEVENTMSG\fP. .TP \fBPTRACE_O_TRACEEXIT\fP (depuis Linux\ 2.5.60) Arrêter l'observé à la terminaison. Un \fBwaitpid\fP(2) par l'observateur renverra une valeur \fIstatus\fP comme .IP .nf status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8)) .fi .IP L'état de fin de l'observé peut être récupéré avec \fBPTRACE_GETEVENTMSG\fP. .IP L'observé est arrêté tôt dans la terminaison du processus, alors que les registres sont toujours disponibles, ce qui permet au processus utilisant \fBptrace\fP() de voir où la terminaison s'est produite, alors que la notification de terminaison normale a lieu à la fin de cette terminaison. Même si le contexte est disponible, l'observateur ne peut pas empêcher la terminaison à ce moment là. .TP \fBPTRACE_O_TRACEFORK\fP (depuis Linux\ 2.5.46) Arrêter l'observé au prochain \fBfork\fP(2) et commencer automatiquement à suivre le nouveau processus créé, qui démarrera avec un signal \fBSIGSTOP\fP, ou \fBPTRACE_EVENT_STOP\fP si \fBPTRACE_SEIZE\fP est utilisé. Un \fBwaitpid\fP(2) par l'observateur renverra une valeur \fIstatus\fP comme .IP .nf status>>8 == (SIGTRAP | (PTRACE_EVENT_FORK<<8)) .fi .IP Le PID du nouveau processus peut être récupéré avec \fBPTRACE_GETEVENTMSG\fP. .TP \fBPTRACE_O_TRACESYSGOOD\fP (depuis Linux\ 2.4.6) Lors des interceptions d'appel système, positionner le bit\ 7 sur le numéro de signal (envoyer \fISIGTRAP|0x80\fP). Cela facilite pour l'observateur la distinction entre les interceptions normales et celles provoquées par un appel système. .TP \fBPTRACE_O_TRACEVFORK\fP (depuis Linux\ 2.5.46) Arrêter l'observé au prochain \fBvfork\fP(2) et commencer automatiquement à suivre le nouveau processus créé, qui démarrera avec un signal \fBSIGSTOP\fP, ou \fBPTRACE_EVENT_STOP\fP si \fBPTRACE_SEIZE\fP est utilisé. Un \fBwaitpid\fP(2) par l'observateur renverra une valeur \fIstatus\fP comme .IP .nf status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK<<8)) .fi .IP Le PID du nouveau processus peut être récupéré avec \fBPTRACE_GETEVENTMSG\fP. .TP \fBPTRACE_O_TRACEVFORKDONE\fP (depuis Linux\ 2.5.60) Arrêter l'observé à la fin du prochain \fBvfork\fP(2). Un \fBwaitpid\fP(2) par l'observateur renverra une valeur \fIstatus\fP comme .IP .nf status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK_DONE<<8)) .fi .IP Le PID du nouveau processus peut (depuis Linux\ 2.6.18) être récupéré avec \fBPTRACE_GETEVENTMSG\fP. .TP \fBPTRACE_O_TRACESECCOMP\fP (depuis Linux\ 3.5) Arrêter l'observé quand une règle \fBSECCOMP_RET_TRACE\fP de \fBseccomp\fP(2) est déclenchée. Un \fBwaitpid\fP(2) par l'observateur renverra une valeur \fIstatus\fP comme .IP .nf status>>8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP<<8)) .fi .IP Si cela entraîne un arrêt \fBPTRACE_EVENT\fP, c'est équivalent à un arrêt\-entrée\-appel\-système. Pour des détails, voir la remarque sur \fBPTRACE_EVENT_SECCOMP\fP ci\-dessous. Les données du message de l'événement seccomp (issues de la partie \fBSECCOMP_RET_DATA\fP de la règle du filtre seccomp) peuvent être récupérées avec \fBPTRACE_GETEVENTMSG\fP. .TP \fBPTRACE_O_SUSPEND_SECCOMP\fP (depuis Linux\ 4.3) .\" commit 13c4a90119d28cfcb6b5bdd820c233b86c2b0237 Suspendre les protections seccomp de l'observé. Cela s'applique quel que soit le mode et peut être utilisé lorsque l'observé n'a pas encore installé de filtres seccomp. Cela veut dire qu'un cas d'utilisation valable consiste à suspendre les protections seccomp d'un observé avant qu'elles ne soient installées par l'observé, laisser l'observé installer les filtres et vider cet attribut quand les filtres doivent être réactivés. La définition de cette option implique que l'observateur ait la capacité \fBCAP_SYS_ADMIN\fP, n'ait pas de protection seccomp installée et n'ait pas de \fBPTRACE_O_SUSPEND_SECCOMP\fP positionné sur lui\-même. .RE .TP \fBPTRACE_GETEVENTMSG\fP (depuis Linux\ 2.5.46) Récupérer un message (dans un \fIunsigned long\fP) concernant l'événement ptrace qui vient d'arriver, en le plaçant à l'adresse \fIdata\fP de l'observateur. Pour \fBPTRACE_EVENT_EXIT\fP, il s'agit du code de retour de l'observé. Pour \fBPTRACE_EVENT_FORK\fP, \fBPTRACE_EVENT_VFORK\fP, \fBPTRACE_EVENT_VFORK_DONE\fP et \fBPTRACE_EVENT_CLONE\fP, il s'agit du PID du nouveau processus. Pour \fBPTRACE_EVENT_SECCOMP\fP, il s'agit des \fBSECCOMP_RET_DATA\fP du filtre \fBseccomp\fP(2) associées à la règle déclenchée (\fIaddr\fP est ignorée). .TP \fBPTRACE_CONT\fP Redémarrer l'observé arrêté. Si \fIdata\fP est non nul, il est interprété comme un numéro de signal à distribuer à l'observé\ ; sinon aucun signal n'est distribué. L'observateur peut ainsi contrôler si un signal envoyé à l'observé doit lui être distribué ou non (\fIaddr\fP est ignoré). .TP \fBPTRACE_SYSCALL\fP, \fBPTRACE_SINGLESTEP\fP Redémarrer l'observé arrêté comme pour \fBPTRACE_CONT\fP, mais en s'arrangeant pour qu'il soit arrêté à la prochaine entrée ou sortie d'un appel système, ou après la prochaine instruction, respectivement (l'observé sera aussi arrêté par l'arrivée d'un signal). Du point de vue de l'observateur, l'observé semblera être arrêté par \fBSIGTRAP\fP. Ainsi, pour \fBPTRACE_SYSCALL\fP l'idée est d'inspecter les arguments de l'appel système au premier arrêt puis de faire un autre \fBPTRACE_SYSCALL\fP et d'inspecter la valeur de retour au second arrêt. Le paramètre \fIdata\fP est interprété comme pour \fBPTRACE_CONT\fP (\fIaddr\fP est ignoré). .TP \fBPTRACE_SET_SYSCALL\fP (depuis Linux\ 2.6.16) .\" commit 3f471126ee53feb5e9b210ea2f525ed3bb9b7a7f .\" As of 4.19-rc2 .\" commit 27aa55c5e5123fa8b8ad0156559d34d7edff58ca .\" see change_syscall in tools/testing/selftests/seccomp/seccomp_bpf.c .\" and also strace's linux/*/set_scno.c files. Lorsqu'il est en arrêt\-entrée\-appel\-système, passer le numéro de l'appel système qui va être exécuté à celui indiqué dans le paramètre \fIdata\fP. Le paramètre \fIaddr\fP est ignoré. Cette requête n'est actuellement prise en charge que sur arm (et arm64, quoique uniquement à des fins de rétrocompatibilité), mais la plupart des autres architectures ont d'autres moyens de faire cela (en général en modifiant le registre qui a passé l'appel système au code au niveau de l'utilisateur). .TP \fBPTRACE_SYSEMU\fP, \fBPTRACE_SYSEMU_SINGLESTEP\fP (depuis Linux\ 2.6.14) .\" As at 3.7 Pour \fBPTRACE_SYSEMU\fP, continuer puis s'arrêter lors du prochain appel système, qui ne sera pas exécuté. Voir la documentation des syscall\-stops ci\-dessous. Pour \fBPTRACE_SYSEMU_SINGLESTEP\fP, faire la même chose, mais exécuter pas à pas s'il ne s'agit pas d'un appel système. Cette fonction est utilisée par des programmes comme User Mode Linux, qui veulent émuler tous les appels système de l'observé. Le paramètre \fIdata\fP est interprété comme pour \fBPTRACE_CONT\fP. L'argument \fIaddr\fP est ignoré. Ces requêtes ne sont pour l'instant disponibles que sur x86. .TP \fBPTRACE_LISTEN\fP (depuis Linux\ 3.4) Redémarrer l'observé arrêté, mais en l'empêchant de s'exécuter. L'état résultant de l'observé est similaire a celui d'un processus qui a été arrêté par un \fBSIGSTOP\fP (ou autre signal d'arrêt). Consultez la sous\-section \fBArrêt\-groupe\fP pour des renseignements supplémentaires. \fBPTRACE_LISTEN\fP ne fonctionne que sur les observés attachés par \fBPTRACE_SEIZE\fP. .TP \fBPTRACE_KILL\fP Envoyer à l'observé un signal \fBSIGKILL\fP pour le terminer (\fIaddr\fP et \fIdata\fP sont ignorés). .IP .\" [Note from Denys Vlasenko: .\" deprecation suggested by Oleg Nesterov. He prefers to deprecate it .\" instead of describing (and needing to support) PTRACE_KILL's quirks.] \fICette opération est obsolète, ne l'utilisez pas.\fP À la place, envoyez un \fBSIGKILL\fP directement en utilisant \fBkill\fP(2) ou \fBtgkill\fP(2). Le problème avec \fBPTRACE_KILL\fP est qu'il nécessite que l'observé soit en arrêt\-distribution\-signal, sinon cela risque de ne pas fonctionner (c'est\-à\-dire risque de se terminer avec succès sans tuer l'observé). En revanche, envoyer \fBSIGKILL\fP directement n'est pas concerné par cette limite. .TP \fBPTRACE_INTERRUPT\fP (depuis Linux\ 3.4) Arrêter un observé. Si l’observé est en cours d’exécution ou en sommeil dans l’espace utilisateur et que \fBPTRACE_SYSCALL\fP est effectif, l’appel système est interrompu et l'arrêt\-sortie\-appel\-système est signalé (l’appel système interrompu est redémarré quand l’observé est redémarré). Si l’observé avait déjà été arrêté par un signal et que \fBPTRACE_LISTEN\fP lui avait été envoyé, l’observé s’arrête avec \fBPTRACE_EVENT_STOP\fP et \fBWSTOPSIG(status)\fP renvoie le signal d’arrêt. Si n’importe quel autre arrêt\-ptrace est créé en même temps (par exemple, si un signal est envoyé à l’observé), cet arrêt\-ptrace arrive. Si rien de ce qui précède ne s’applique (par exemple si l’observé est en cours d’exécution en espace utilisateur), il s’arrête avec \fBPTRACE_EVENT_STOP\fP avec \fIWSTOPSIG(status)\fP == \fBSIGTRAP\fP. \fBPTRACE_INTERRUPT\fP ne fonctionne que sur les observés attachés par \fBPTRACE_SEIZE\fP. .TP \fBPTRACE_ATTACH\fP .\" No longer true (removed by Denys Vlasenko, 2011, who remarks: .\" "I think it isn't true in non-ancient 2.4 and in Linux 2.6/3.x. .\" Basically, it's not true for any Linux in practical use. .\" ; the behavior of the tracee is as if it had done a .\" .BR PTRACE_TRACEME . .\" The calling process actually becomes the parent of the tracee .\" process for most purposes (e.g., it will receive .\" notification of tracee events and appears in .\" .BR ps (1) .\" output as the tracee's parent), but a .\" .BR getppid (2) .\" by the tracee will still return the PID of the original parent. Attacher le processus numéro \fIpid\fP, pour le suivre. L'observé va recevoir un \fBSIGSTOP\fP, mais il ne sera peut\-être pas arrêté tout de suite, utilisez \fBwaitid\fP(2) pour attendre son arrêt. Consultez la sous\-section \fBAttachement et détachement\fP pour obtenir de plus amples renseignements (\fIaddr\fP et \fIdata\fP sont ignorés). .IP Le droit d'effectuer un \fBPTRACE_ATTACH\fP est géré par la vérification \fBPTRACE_MODE_ATTACH_REALCREDS\fP du mode d'accès de ptrace\ ; voir ci\-dessous. .TP \fBPTRACE_SEIZE\fP (depuis Linux\ 3.4) .\" .\" Noted by Dmitry Levin: .\" .\" PTRACE_SEIZE was introduced by commit v3.1-rc1~308^2~28, but .\" it had to be used along with a temporary flag PTRACE_SEIZE_DEVEL, .\" which was removed later by commit v3.4-rc1~109^2~20. .\" .\" That is, [before] v3.4 we had a test mode of PTRACE_SEIZE API, .\" which was not compatible with the current PTRACE_SEIZE API introduced .\" in Linux 3.4. .\" Attacher au processus indiqué dans \fIpid\fP, en faire un observé du processus appelant. Contrairement à \fBPTRACE_ATTACH\fP, \fBPTRACE_SEIZE\fP n'arrête pas le processus. Les arrêts\-groupe sont signalés en tant que \fBPTRACE_EVENT_STOP\fP et \fIWSTOPSIG(status)\fP renvoie le signal d'arrêt. Les enfants automatiquement attachés avec \fBPTRACE_EVENT_STOP\fP et \fIWSTOPSIG(status)\fP renvoient \fBSIGTRAP\fP au lieu de recevoir un signal \fBSIGSTOP\fP. \fBexecve\fP(2) n'envoie pas d'autres \fBSIGTRAP\fP. Seul un processus \fBPTRACE_SEIZE\fPé peut accepter des commandes \fBPTRACE_INTERRUPT\fP et \fBPTRACE_LISTEN\fP. Le comportement «\ seized\ » qui vient d'être décrit est récupéré par les enfants automatiquement attachés en utilisant \fBPTRACE_O_TRACEFORK\fP, \fBPTRACE_O_TRACEVFORK\fP et \fBPTRACE_O_TRACECLONE\fP. \fIaddr\fP doit être de zéro. \fIdata\fP contient un masque de bit des options ptrace à activer immédiatement. .IP .\" Le droit d'effectuer un \fBPTRACE_SEIZE\fP est géré par une vérification \fBPTRACE_MODE_ATTACH_REALCREDS\fP du mode d'accès ptrace\ ; voir ci\-dessous. .TP \fBPTRACE_SECCOMP_GET_FILTER\fP (depuis Linux\ 4.4) .\" commit f8e529ed941ba2bbcbf310b575d968159ce7e895 Cette opération autorise l'observateur à vider les filtres BPF classiques de l'observé. .IP \fIaddr\fP est un entier indiquant l'index du filtre à vider. Le filtre le plus récemment installé a le numéro d'index\ \fB0\fP. Si \fIaddr\fP est supérieur aux numéros des filtres installés, l'opération échoue avec l'erreur \fBENOENT\fP. .IP \fIdata\fP est soit un pointeur vers un tableau \fIstruct sock_filter\fP assez grand pour stocker le programme BPF, soit NULL si le programme ne va pas être stocké. .IP En cas de succès, le code de retour est le nombre d'instructions du programme BPF. Si \fIdata\fP était NULL, ce code de retour peut être utilisé pour dimensionner correctement le tableau \fIstruct sock_filter\fP passé dans un appel ultérieur. .IP Cette opération échoue avec l'erreur \fBEACCES\fP si l'appelant n'a pas la capacité \fBCAP_SYS_ADMIN\fP ou s'il est en mode seccomp filtré ou restreint. Si le filtre auquel renvoie \fIaddr\fP n'est pas un filtre BPF classique, l'opération échoue avec l'erreur \fBEMEDIUMTYPE\fP. .IP Cette opération n'est disponible que si le noyau a été configuré avec les options \fBCONFIG_SECCOMP_FILTER\fP et \fBCONFIG_CHECKPOINT_RESTORE\fP. .TP \fBPTRACE_DETACH\fP .\" Relancer l'observé arrêté comme avec \fBPTRACE_CONT\fP, mais en commençant par s'en détacher. Sous Linux un observé peut être détaché ainsi quelque soit la méthode employée pour démarrer le suivi (\fIaddr\fP est ignoré). .TP \fBPTRACE_GET_THREAD_AREA\fP (depuis Linux\ 2.6.0) Cette opération effectue une tâche identique à \fBget_thread_area\fP(2). Elle lit l'entrée TLS dans le GDT dont l'index est donné dans \fIaddr\fP, mettant une copie de l'entrée dans la \fIstruct user_desc\fP vers laquelle pointe \fIdata\fP (contrairement à \fBget_thread_area\fP(2), \fIentry_number\fP de la \fIstruct user_desc\fP est ignorée). .TP \fBPTRACE_SET_THREAD_AREA\fP (depuis Linux\ 2.6.0) Cette opération effectue la même tâche que \fBset_thread_area\fP(2). Elle positionne l'entrée TLS dans le GDT dont l'index est donné dans \fIaddr\fP, en lui affectant les données fournies dans la \fIstruct user_desc\fP vers laquelle pointe \fIdata\fP (contrairement à \fBset_thread_area\fP(2), \fIentry_number\fP de la \fIstruct user_desc\fP est ignorée\ ; autrement dit, cette opération de ptrace ne peut pas être utilisée pour affecter une entrée TLS libre). .TP \fBPTRACE_GET_SYSCALL_INFO\fP (depuis Linux\ 5.3) .\" commit 201766a20e30f982ccfe36bebfad9602c3ff574a Récupérer des informations sur l'appel système qui a provoqué l'arrêt. Les informations sont placées dans le tampon vers lequel pointe le paramètre \fIdata\fP, lequel doit être un pointeur vers un tampon de type \fIstruct ptrace_syscall_info\fP. Le paramètre \fIaddr\fP contient la taille du tampon vers lequel pointe le paramètre \fIdata\fP (à savoir \fIsizeof(struct ptrace_syscall_info)\fP). Le code de retour contient le nombre d'octets que le noyau peut écrire. Si la taille des données que le noyau doit écrire dépasse celle indiquée par le paramètre \fIaddr\fP, les données de sortie sont tronquées. .IP La structure \fIptrace_syscall_info\fP contient les champs suivants\ : .IP .in +4n .EX struct ptrace_syscall_info { __u8 op; /* Type d'appel système d'arrêt */ __u32 arch; /* Valeur AUDIT_ARCH_*\ ; voir seccomp(2) */ __u64 instruction_pointer; /* Pointeur vers l'instruction du processeur */ __u64 stack_pointer; /* Pointeur vers la pile du processeur */ union { struct { /* op == PTRACE_SYSCALL_INFO_ENTRY */ __u64 nr; /* Numéro de l'appel système */ __u64 args[6]; /* Paramètres de l'appel système */ } entry; struct { /* op == PTRACE_SYSCALL_INFO_EXIT */ __s64 rval; /* Code de retour de l'appel système */ __u8 is_error; /* Attribut d'erreur de l'appel système\ ; Booléen\ : rval contient\-il un code d'erreur (\-ERRCODE) ou un code de retour de non erreur\ ? */ } exit; struct { /* op == PTRACE_SYSCALL_INFO_SECCOMP */ __u64 nr; /* Numéro de l'appel système */ __u64 args[6]; /* Paramètres de l'appel système */ __u32 ret_data; /* Partie SECCOMP_RET_DATA de la valeur de retour de SECCOMP_RET_TRACE */ } seccomp; }; }; .EE .in .IP Les champs \fIop\fP, \fIarch\fP, \fIinstruction_pointer\fP et \fIstack_pointer\fP sont définis pour tous les types d'arrêts de l'appel système ptrace. Le reste de la structure est une union\ ; on ne doit lire que les champs significatifs pour le type d'arrêt de l'appel système indiqué par le champ \fIop\fP. .IP Le champ \fIop\fP prend une des valeurs suivantes (définies dans \fI\fP), indiquant le type d'arrêt qui s'est produit et la partie remplie de l'union\ : .RS .TP \fBPTRACE_SYSCALL_INFO_ENTRY\fP Le composant \fIentry\fP de l'union contient des informations liées à un arrêt d'entrée appel système. .TP \fBPTRACE_SYSCALL_INFO_EXIT\fP Le composant \fIexit\fP de l'union contient des informations sur un arrêt de sortie d'appel système. .TP \fBPTRACE_SYSCALL_INFO_SECCOMP\fP Le composant \fIseccomp\fP de l'union contient des informations concernant un arrêt \fBPTRACE_EVENT_SECCOMP\fP. .TP \fBPTRACE_SYSCALL_INFO_NONE\fP Aucun composant de l'union ne contient d'informations pertinentes. .RE .IP .\" In case of system call entry or exit stops, the data returned by \fBPTRACE_GET_SYSCALL_INFO\fP is limited to type \fBPTRACE_SYSCALL_INFO_NONE\fP unless \fBPTRACE_O_TRACESYSGOOD\fP option is set before the corresponding system call stop has occurred. .SS "Mort sous ptrace" Quand un processus (éventuellement multithreadé) reçoit un signal pour le tuer (un dont la disposition est configurée à \fBSIG_DFL\fP et dont l'action par défaut est de tuer le processus), tous les threads se terminent. Chaque observé signale sa mort à son ou ses observateurs. La notification de cet événement est distribuée par \fBwaitpid\fP(2). .PP Remarquez que le signal tueur provoquera d'abord un arrêt\-distribution\-signal (sur un seul observé) et, seulement après être injecté par l'observateur (ou après être envoyé à un thread qui n'est pas suivi), la mort du signal arrivera sur \fItous\fP les observés d'un processus multithreadé (le terme «\ arrêt\-distribution\-signal\ » est expliqué plus bas). .PP \fBSIGKILL\fP ne génère pas d'arrêt\-distribution\-signal et l'observateur ne peut par conséquent pas le supprimer. \fBSIGKILL\fP tue même à l'intérieur des appels systèmes (arrêt\-sortie\-appel\-système n'est pas créé avant la mort par \fBSIGKILL\fP). L'effet direct est que \fBSIGKILL\fP tue toujours le processus (tout ses threads), même si certains threads du processus sont suivis avec ptrace. .PP Quand l'observé appelle \fB_exit\fP(2), il signale sa mort à son observateur. Les autres threads ne sont pas concernés. .PP Quand n'importe quel thread exécute \fBexit_group\fP(2), tous les observés de son groupe de threads signalent leur mort à leur observateur. .PP Si l'option \fBPTRACE_O_TRACEEXIT\fP est active, \fBPTRACE_EVENT_EXIT\fP arrivera avant la mort réelle. Cela s'applique aux terminaisons avec \fBexit\fP(2), \fBexit_group\fP(2) et aux morts de signal (sauf \fBSIGKILL\fP, selon la version du noyau\ ; voir les BOGUES ci\-dessous), et lorsque les threads sont détruits par \fBexecve\fP(2) dans un processus multithreadé. .PP L'observateur ne peut pas assumer que l'observé arrêté\-ptrace existe. L'observé risque de mourir avant d'être arrêté dans plusieurs cas (comme avec \fBSIGKILL\fP). Par conséquent, le tracé doit être préparé pour traiter une erreur \fBESRCH\fP sur n'importe quelle opération ptrace. Malheureusement, la même erreur est renvoyée si l'observé existe mais n'est pas arrêté\-ptrace (pour les commandes qui nécessitent un observé arrêté), ou s'il n'est pas suivi par le processus qui a envoyé l'appel ptrace. L'observateur doit garder une trace de l'état arrêté ou en fonctionnement de l'observé, et interpréter \fBESRCH\fP comme «\ l'observé s'est achevé de manière inattendue\ » seulement s'il sait que l'observé est effectivement entré en arrêt\-ptrace. Remarquez qu'il n'est pas garanti que \fIwaitpid(WNOHANG)\fP signale de façon fiable l'état de mort de l'observé si une opération ptrace renvoie \fBESRCH\fP. \fIwaitpid(WNOHANG)\fP pourrait plutôt renvoyer \fB0\fP. Autrement dit, l'observé pourrait «\ ne pas être encore mort\ », mais déjà refuser des requêtes ptrace. .PP L'observateur ne peut pas assumer que l'observé finit \fItoujours\fP sa vie en signalant \fIWIFEXITED(status)\fP ou \fIWIFSIGNALED(status)\fP\ ; dans certains cas ça n'arrive pas. Par exemple si un thread différent du leader de groupe de threads fait un \fBexecve\fP(2), il disparaît\ ; son PID ne sera plus jamais vu, tous les arrêts suivants de ptrace seront signalés sous le PID du leader de groupe de threads. .SS "États arrêtés" Deux états existent pour un observé\ : en cours d'exécution ou à l'arrêt. Du point de vue de ptrace, un observé qui est bloqué dans un appel système (comme \fBread\fP(2), \fBpause\fP(2),\ etc.) est néanmoins considéré en cours d’exécution, même si l’observé est bloqué depuis longtemps. L’état de l’observé après \fBPTRACE_LISTEN\fP est en quelque sorte une zone d’ombre\ : il n’est dans aucun arrêt\-ptrace (les commandes ptrace n’auront aucun effet sur lui et il distribuera des notifications \fBwaitpid\fP(2)), mais il pourrait aussi être considéré «\ arrêté\ » parce qu’il n’est pas en train d’exécuter des instructions (pas de programmation) et, s’il était en arrêt\-groupe avant \fBPTRACE_LISTEN\fP, il ne répondra pas aux signaux avant de recevoir \fBSIGCONT\fP. .PP De nombreuses sortes d'états sont possibles quand l'observé est arrêté, et les discussions dans ptrace sont souvent confondues. Par conséquent, l'utilisation de termes précis est importante. .PP Dans cette page de manuel, tous les états d'arrêt dans lesquels l'observé est prêt à accepter des commandes ptrace de l'observateur sont appelés \fIarrêt\-ptrace\fP. Les arrêts\-ptrace peuvent ensuite être sous\-divisés en \fIarrêt\-distribution\-signal\fP, \fIarrêt\-groupe\fP, \fIarrêt\-appel\-système\fP,\ \fIarrêt\-PTRACE_EVENT\fP,\ etc. Ces états d'arrêt sont décrits en détail ci\-dessous. .PP Lorsque l'observé en cours d'exécution entre en arrêt\-ptrace, il avise son observateur en utilisant \fBwaitpid\fP(2) (ou un des autres appels système «\ wait\ »). La plupart de cette page de manuel suppose que l'observateur attend avec\ : .PP .in +4n .EX pid = waitpid(pid_ou_moins_1, &status, __WALL); .EE .in .PP .\" Denys Vlasenko: .\" Do we require __WALL usage, or will just using 0 be ok? (With 0, .\" I am not 100% sure there aren't ugly corner cases.) Are the .\" rules different if user wants to use waitid? Will waitid require .\" WEXITED? .\" Les observés arrêtés\-ptrace sont signalés comme renvoyés avec un \fIpid\fP strictement positif et \fIWIFSTOPPED(status)\fP vrai. .PP L'attribut \fB__WALL\fP ne contient pas les attributs \fBWSTOPPED\fP et \fBWEXITED\fP, mais implique leur fonctionnalité. .PP La configuration de l'attribut \fBWCONTINUED\fP en appelant \fBwaitpid\fP(2) n'est pas conseillée\ : l'état «\ exécuté\ » est relatif au processus et l'utiliser peut embrouiller le vrai parent de l'observé. .PP Utiliser l'attribut \fBWNOHANG\fP pourrait forcer \fBwaitpid\fP(2) à renvoyer \fB0\fP («\ aucun résultat d'attente encore disponible\ ») même si l'observateur sait qu'il devrait y avoir une notification. Exemple\ : .PP .in +4n .EX errno = 0; ptrace(PTRACE_CONT, pid, 0L, 0L); if (errno == ESRCH) { /* l'observé est mort */ r = waitpid(tracee, &status, __WALL | WNOHANG); /* r peut encore valoir 0 ici\ ! */ } .EE .in .\" FIXME . .\" waitid usage? WNOWAIT? .\" describe how wait notifications queue (or not queue) .PP Les sortes d'arrêts\-ptrace suivants existent\ : arrêts\-distribution\-signal, arrêts\-groupe, arrêts \fBPTRACE_EVENT\fP et arrêts\-appel\-système. Ils sont signalés par \fBwaitpid\fP(2) avec \fIWIFSTOPPED(status)\fP vrai. Ils peuvent être distingués en examinant la valeur \fIstatus>>8\fP, et en cas d'ambiguïté dans cette valeur, en faisant une requête \fBPTRACE_GETSIGINFO\fP (remarque\ : la macro \fIWSTOPSIG(status)\fP ne peut pas être utilisée pour réaliser cet examen, car elle renvoie la valeur \fI(status>>8)\ &\ 0xff\fP.) .SS Arrêt\-distribution\-signal Quand un processus (éventuellement multithreadé) reçoit n'importe quel signal sauf \fBSIGKILL\fP, le noyau choisi un thread arbitraire pour traiter le signal (si le signal est créé avec \fBtgill\fP(2), le thread cible peut être explicitement choisi par l'appelant). Si le thread choisi est observé, il entre en arrêt\-distribution\-signal. À ce moment là, le signal n'est pas encore distribué au processus, et peut être supprimé par l'observateur. Si l'observateur ne supprime pas le signal, il passe le signal à l'observé lors de la requête suivante de redémarrage de ptrace. Cette deuxième étape de distribution de signal est appelée \fIinjection de signal\fP dans cette page de manuel. Remarquez que si le signal est bloqué, l'arrêt\-distribution\-signal n'arrive pas avant que le signal soit débloqué, à l'exception habituelle que \fBSIGSTOP\fP ne peut pas être bloqué. .PP L'arrêt\-distribution\-signal est respecté par l'observateur tant que \fBwaitpid\fP(2) retourne avec \fIWIFSTOPPED(status)\fP vrai, avec le signal renvoyé par \fIWSTOPSIG(status)\fP. Si le signal est \fBSIGTRAP\fP, cela pourrait être un arrêt\-ptrace de nature différente\ ; consultez les sections \fBArrêts\-appel\-système\fP et \fBexecve(2) sous ptrace\fP plus bas pour obtenir de plus amples précisions. Si \fIWSTOPSIG(status)\fP renvoie un signal d'arrêt, cela pourrait être un arrêt\-groupe\ ; voir ci\-dessous. .SS "Injection et suppression de signal" Après un arrêt\-distribution\-signal respecté par l'observateur, l'observateur devrait redémarrer l'observé avec l'appel .PP .in +4n .EX ptrace(PTRACE_restart, pid, 0, sig) .EE .in .PP où \fBPTRACE_restart\fP est une des requêtes ptrace de redémarrage. Si \fIsig\fP est \fB0\fP, alors aucun signal n'est distribué. Sinon, le signal \fIsig\fP est distribué. Cette opération est appelée \fIinjection de signal\fP dans cette page de manuel, pour la distinguer de l'arrêt\-distribution\-signal. .PP La valeur de \fIsig\fP peut être différente de celle de \fIWSTOPSIG(status)\fP\ : l'observateur peut provoquer l'injection d'un autre signal. .PP Remarquez qu'un signal supprimé provoque toujours un retour prématuré des appels système. Dans ce cas, les appels système seront redémarrés\ : l'observateur forcera l'observé à réexécuter l'appel système interrompu (ou l'appel système \fBrestart_syscall\fP(2) pour les quelques appels système qui utilisent un autre mécanisme de redémarrage) si l'observateur utilise \fBPTRACE_SYSCALL\fP. Même les appels système (comme \fBpoll\fP(2)) qui ne sont pas redémarrables après le signal sont redémarrés après la suppression du signal\ ; cependant, des bogues du noyau existent et certains appels système échouent avec \fBEINTR\fP même si aucun signal observable n'est injecté dans l'observé. .PP Lors du redémarrage des commandes ptrace émises dans d'autres arrêts\-ptrace qu'arrêt\-distribution\-signal, l'injection de signal n'est pas garantie, même si \fIsig\fP est non nul. Aucune erreur n'est signalée\ ; un \fIsig\fP non nul risque simplement d'être ignoré. Les utilisateurs de ptrace ne devraient pas essayer de «\ créer un nouveau signal\ » de cette façon\ : utilisez plutôt \fBtgkill\fP(2). .PP Le fait que des requêtes d'injection de signal puissent être ignorées lors du redémarrage de l'observé après des arrêts ptrace qui ne sont pas des arrêts\-distribution\-signal est une source de confusion pour les utilisateurs de ptrace. Un scénario typique est que l'observateur remarque un arrêt\-groupe, le confonde avec un arrêt\-distribution\-signal, et redémarre l'observé avec .PP .in +4n .EX ptrace(PTRACE_restart, pid, 0, stopsig) .EE .in .PP dans le but d'injecter \fIstopsig\fP, mais \fIstopsig\fP sera ignoré et l'observé continuera de fonctionner. .PP Le signal \fBSIGCONT\fP a pour effet de bord de réveiller (tous les threads d')un processus arrêté\-groupe. Cet effet de bord arrive avant un arrêt\-distribution\-signal. L'observateur ne peut pas supprimer cet effet de bord (il ne peut que supprimer l'injection de signal, qui force seulement le gestionnaire de \fBSIGCONT\fP à ne pas être exécuté dans l'observé, si un gestionnaire de ce type est installé). En fait, le réveil depuis un arrêt\-groupe pourrait être suivi par un arrêt\-distribution\-signal pour le ou les signaux \fIdifférents\fP de \fBSIGCONT\fP, s'ils étaient en attente quand \fBSIGCONT\fP a été distribué. Autrement dit, \fBSIGCONT\fP pourrait ne pas être le premier signal remarqué par l'observé après avoir été envoyé. .PP L'arrêt de signaux force (tous les threads d')un processus à entrer en arrêt\-groupe. Cet effet de bord arrive après une injection de signal, et peut par conséquent être supprimé par l'observateur. .PP .\" In the Linux 2.4 sources, in arch/i386/kernel/signal.c::do_signal(), .\" there is: .\" .\" /* The debugger continued. Ignore SIGSTOP. */ .\" if (signr == SIGSTOP) .\" continue; Sous Linux\ 2.4 et les versions précédentes, le signal \fBSIGSTOP\fP ne pouvait pas être injecté. .PP \fBPTRACE_GETSIGINFO\fP peut être utilisé pour récupérer une structure \fIsiginfo_t\fP qui correspond au signal distribué. \fBPTRACE_SETSIGINFO\fP pourrait être utilisé pour le modifier. Si \fBPTRACE_SETSIGINFO\fP a été utilisé pour modifier \fIsiginfo_t\fP, le champ \fIsi_signo\fP et le paramètre \fIsig\fP de la commande de redémarrage doivent correspondre, sinon le résultat est indéfini. .SS Arrêt\-groupe Quand un processus (éventuellement multithreadé) reçoit un signal d'arrêt, tous les threads s'arrêtent. Si certains threads sont suivis, ils entrent en arrêt\-groupe. Remarquez que le signal d'arrêt provoquera d'abord un arrêt\-distribution\-signal (sur un seul observé) et, seulement après avoir été injecté par l'observateur (ou après avoir été envoyé à un thread qui n'est pas suivi), l'arrêt\-groupe sera initié sur \fItous\fP les observés d'un processus multithreadé. Comme d'habitude, tous les observés signalent leur arrêt\-groupe séparément à l'observateur correspondant. .PP L'arrêt\-groupe est respecté par l'observateur tant que \fBwaitpid\fP(2) retourne avec \fIWIFSTOPPED(status)\fP vrai, avec le signal d'arrêt disponible par l'intermédiaire de \fIWSTOPSIG(status)\fP. Le même résultat est renvoyé par d'autres classes d'arrêts\-ptrace, par conséquent la méthode conseillée est de réaliser l'appel .PP .in +4n .EX ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo) .EE .in .PP L'appel peut être évité si le signal n'est pas \fBSIGSTOP\fP, \fBSIGTSTP\fP, \fBSIGTTIN\fP ou \fBSIGTTOU\fP\ ; seuls ces quatre signaux sont des signaux d'arrêt. Si l'observateur voit autre chose, ce ne peut pas être un arrêt\-groupe. Sinon, l'observateur doit appeler \fBPTRACE_GETSIGINFO\fP. Si \fBPTRACE_GETSIGINFO\fP échoue avec \fBEINVAL\fP, alors c'est définitivement un arrêt\-groupe (d'autres codes d'échec sont possibles, comme \fBESRCH\fP («\ pas de processus de ce type\ ») si un \fBSIGKILL\fP a tué l'observé). .PP Si l’observé était attaché en utilisant \fBPTRACE_SEIZE\fP, un arrêt\-groupe est indiqué par \fBPTRACE_EVENT_STOP\fP\ : \fIstatus>>16 == PTRACE_EVENT_STOP\fP. Cela permet la détection d’arrêts\-groupe sans nécessiter d’appel \fBPTRACE_GETSIGINFO\fP supplémentaire. .PP Depuis Linux\ 2.6.38, après que l'observateur a vu l'arrêt\-ptrace de l'observé et jusqu'à ce qu'il le redémarre ou le tue, l'observé ne fonctionnera pas, et n'enverra pas de notification (sauf mort par \fBSIGKILL\fP) à l'observateur, même si l'observateur entre dans un autre appel \fBwaitpid\fP(2). .PP Le comportement du noyau décrit dans le paragraphe précédent pose un problème avec la gestion transparente de signaux d'arrêt. Si l'observateur redémarre l'observé après un arrêt\-groupe, le signal d'arrêt est effectivement ignoré —\ l'observé ne reste pas arrêté, il fonctionne. Si l'observateur ne redémarre pas l'observé avant d'entrer dans le prochain \fBwaitpid\fP(2), les signaux \fBSIGCONT\fP suivants ne seront pas signalés à l'observateur\ ; cela pourrait forcer des signaux \fBSIGCONT\fP à être sans effet sur l'observé. .PP Depuis Linux 3.4, une méthode permet d'éviter ce problème\ : à la place de \fBPTRACE_CONT\fP, une commande \fBPTRACE_LISTEN\fP peut être utilisée pour redémarrer un observé de façon à ce qu'il ne s'exécute pas, mais attende un nouvel événement qu'il peut signaler à l'aide de \fBwaitpid\fP(2) (comme s'il était redémarré par un \fBSIGCONT\fP). .SS "Arrêts PTRACE_EVENT" Si l'observateur configure des options \fBPTRACE_O_TRACE_*\fP, l'observé entrera en arrêts\-ptrace appelés arrêts \fBPTRACE_EVENT\fP. .PP Les arrêts \fBPTRACE_EVENT\fP sont respectés par l'observateur pendant que \fBwaitpid\fP(2) renvoie \fIWIFSTOPPED(status)\fP et que \fIWSTOPSIG(status)\fP renvoie \fBSIGTRAP\fP (ou pour \fBPTRACE_EVENT_STOP\fP, renvoie le signal d'arrêt si l'observé est dans un arrêt de groupe). Un bit supplémentaire est configuré dans l'octet le plus haut du mot d'état\ : la valeur \fIstatus>>8\fP sera .PP .in +4n .EX ((PTRACE_EVENT_foo<<8) | SIGTRAP). .EE .in .PP Les événements suivants existent. .TP \fBPTRACE_EVENT_VFORK\fP Arrêt avant de revenir de \fBvfork\fP(2) ou \fBclone\fP(2) avec l'attribut \fBCLONE_VFORK\fP. Quand l'observé est continué après cet arrêt, il attendra une sortie ou exécution de l'enfant avant de continuer son exécution (autrement dit, le comportement normal avec \fBvfork\fP(2)). .TP \fBPTRACE_EVENT_FORK\fP Arrêt avant de revenir de \fBfork\fP(2) ou \fBclone\fP(2) avec le signal de sortie configuré à \fBSIGCHLD\fP. .TP \fBPTRACE_EVENT_CLONE\fP Arrêt avant de revenir de \fBclone\fP(2). .TP \fBPTRACE_EVENT_VFORK_DONE\fP Arrêt avant de revenir de \fBvfork\fP(2) ou \fBclone\fP(2) avec l'attribut \fBCLONE_VFORK\fP, mais après que l'enfant a débloqué son observé par sortie ou exécution. .PP Pour les quatre arrêts décrits ci\-dessus, l'arrêt arrive dans le parent (c'est\-à\-dire l'observé), pas dans le nouveau thread créé. \fBPTRACE_GETEVENTMSG\fP permet de récupérer l'identifiant du nouveau thread. .TP \fBPTRACE_EVENT_EXEC\fP Arrêt avant le retour d'\fBexecve\fP(2). Depuis Linux\ 3.0, \fBPTRACE_GETEVENTMSG\fP renvoie le premier identifiant de thread. .TP \fBPTRACE_EVENT_EXIT\fP Arrêt avant la sortie (y compris la mort depuis \fBexit_group\fP(2)), la mort du signal ou la sortie provoquée par \fBexecve\fP(2) dans un processus multithreadé. \fBPTRACE_GETEVENTMSG\fP renvoie l'état de sortie. Les registres peuvent être examinés (contrairement à quand une «\ vraie\ » sortie arrive). L'observé est toujours actif\ ; il a besoin de \fBPTRACE_CONT\fP ou \fBPTRACE_DETACH\fP pour terminer sa sortie. .TP \fBPTRACE_EVENT_STOP\fP Arrêt causé par la commande \fBPTRACE_INTERRUPT\fP, ou arrêt\-groupe, ou arrêt\-ptrace initial quand un nouvel enfant est attaché (seulement s’il est attaché en utilisant \fBPTRACE_SEIZE\fP). .TP \fBPTRACE_EVENT_SECCOMP\fP Arrêt différé par une règle \fBseccomp\fP(2) sur l'entrée appel système de l'observé quand \fBPTRACE_O_TRACESECCOMP\fP a été positionné par l'observateur. Les données du message de l'événement seccomp (issues de la portion \fBSECCOMP_RET_DATA\fP de la règle de filtrage seccomp) peuvent être récupérées avec \fBPTRACE_GETEVENTMSG\fP. La sémantique de cet arrêt est décrit en détails dans une section distincte ci\-dessous. .PP \fBPTRACE_GETSIGINFO\fP sur les arrêts \fBPTRACE_EVENT\fP renvoie \fBSIGTRAP\fP dans \fIsi_signo\fP, avec \fIsi_code\fP configuré à \fI(event<<8)\ |\ SIGTRAP\fP. .SS Arrêts\-appel\-système Si l'observé était redémarré par \fBPTRACE_SYSCALL\fP ou \fBPTRACE_SYSEMU\fP, l'observé entre en arrêt\-entrée\-appel\-système juste avant d'entrer dans n'importe quel appel système (qui ne sera pas exécuté si le redémarrage utilisait \fBPTRACE_SYSEMU\fP, quels que soient les changements apportés aux registres à ce point ou à la manière dont l'observé redémarre après cet arrêt). Peu importe la méthode qui a conduit en arrêt\-entrée\-appel\-système si l’observateur redémarre l’observé avec \fBPTRACE_SYSCALL\fP, l’observé entre en arrêt\-sortie\-appel\-système quand l’appel système est terminé ou s'il est interrompu par un signal (c'est\-à\-dire qu'un arrêt\-distribution\-signal n'arrive jamais entre un arrêt\-entrée\-appel\-système et un arrêt\-sortie\-appel\-système\ ; il arrive \fIaprès\fP l'arrêt\-sortie\-appel\-système). Si l'observé est poursuivi en utilisant une autre méthode (notamment \fBPTRACE_SYSEMU\fP), aucun arrêt\-sortie\-appel\-système ne se produit. Remarquez que toutes les mentions \fBPTRACE_SYSEMU\fP s'appliquent également à \fBPTRACE_SYSEMU_SINGLESTEP\fP. .PP Toutefois, même si l'observé a été poursuivi en utilisant \fBPTRACE_SYSCALL\fP, il n'est pas garanti que le prochain arrêt sera un arrêt\-sortie\-appel\-système. D'autres possibilités sont que l'observé pourrait s'arrêter dans un arrêt \fBPTRACE_EVENT\fP, sortir (s'il est entré en \fB_exit\fP(2) ou \fBexit_group\fP(2)), être tué par \fBSIGKILL\fP ou mourir silencieusement (s'il s'agit d'un leader de groupe de threads, que l'\fBexecve\fP(2) est arrivé dans un autre thread et que ce thread n'est pas suivi par le même observateur\ ; cette situation sera abordée plus tard). .PP Les arrêt\-entrée\-appel\-système et arrêt\-sortie\-appel\-système sont respectés par l'observateur tant que \fBwaitpid\fP(2) retourne avec \fIWIFSTOPPED(status)\fP vrai, et que \fIWSTOPSIG(status)\fP donne \fBSIGTRAP\fP. Si l'option \fBPTRACE_O_TRACESYSGOOD\fP était configurée par l'observateur, alors \fIWSTOPSIG(status)\fP donnera la valeur (\fISIGTRAP\ |\ 0x80\fP). .PP Les arrêts\-appel\-système peuvent être distingués d'un arrêt\-distribution\-signal avec \fBSIGTRAP\fP en demandant \fBPTRACE_GETSIGINFO\fP pour les cas suivants. .TP \fIsi_code\fP <= 0 \fBSIGTRAP\fP a été distribué comme résultat d'une action en espace utilisateur, par exemple, un appel système (\fBtgkill\fP(2), \fBkill\fP(2), \fBsigqueue\fP(3),\ etc.), l'expiration d'un minuteur POSIX, la modification d'état sur une file de messages POSIX où la fin d'une requête d'E/S asynchrone. .TP \fIsi_code\fP == SI_KERNEL (0x80) \fBSIGTRAP\fP a été envoyé par le noyau. .TP \fIsi_code\fP == SIGTRAP ou \fIsi_code\fP == (SIGTRAP|0x80) C'est un arrêt\-appel\-système. .PP Cependant, les arrêts\-appel\-système arrivent très souvent (deux fois par appel système) et réaliser \fBPTRACE_GETSIGINFO\fP pour chaque arrêt\-appel\-système pourrait être assez coûteux. .PP Certaines architectures permettent de distinguer ces cas en examinant les registres. Par exemple, sur x86, \fIrax\fP == \-\fBENOSYS\fP en arrêt\-entrée\-appel\-système. Puisque \fBSIGTRAP\fP (comme tout autre signal) arrive toujours \fIaprès\fP l'arrêt\-sortie\-appel\-système et que \fIrax\fP ne contient à ce moment presque jamais \-\fBENOSYS\fP, le \fBSIGTRAP\fP ressemble à un «\ arrêt\-appel\-système qui n'est pas un arrêt\-entrée\-appel\-système\ »\ ; autrement dit, il ressemble à un «\ arrêt\-sortie\-appel\-système perdu\ » et peut être détecté de cette façon. Une telle détection est néanmoins fragile, elle est donc a éviter. .PP L'utilisation de l'option \fBPTRACE_O_TRACESYSGOOD\fP est la méthode conseillée pour distinguer les arrêts\-appel\-système des autres sortes d'arrêts\-ptrace, puisqu'il est fiable et n'induit pas de perte de performances. .PP Les arrêt\-entrée\-appel\-système et arrêt\-sortie\-appel\-système ne sont pas différentiables l'un de l'autre. L'observateur doit garder une trace de la suite d'arrêts\-ptrace afin de ne pas mal interpréter un arrêt\-entrée\-appel\-système comme un arrêt\-sortie\-appel\-système ou vice versa. Généralement, l'arrêt\-entrée\-appel\-système est toujours suivi par un arrêt\-sortie\-appel\-système, un arrêt \fBPTRACE_EVENT\fP ou la mort de l'observé\ ; aucune autre sorte d'arrêt\-ptrace ne peut arriver entre\-deux. Toutefois, remarquez que les arrêts seccomp (voir ci\-dessous) peuvent provoquer des arrêts\-sortie\-appel\-système sans arrêt\-entrée\-appel\-système préalable. Si seccomp, il faut faire attention à ne pas mal interpréter de tels arrêts en arrêts\-entrée\-appel\-système. .PP Si suite à un arrêt\-entrée\-appel\-système, l'observateur utilise une commande de redémarrage différente de \fBPTRACE_SYSCALL\fP, l'arrêt\-sortie\-appel\-système n'est pas créé. .PP .\" \fBPTRACE_GETSIGINFO\fP sur les arrêts\-appel\-système renvoie \fBSIGTRAP\fP dans \fIsi_signo\fP, avec \fIsi_code\fP configuré à \fBSIGTRAP\fP ou (\fBSIGTRAP\ |\ 0x80\fP). .SS "Arrêts PTRACE_EVENT_SECCOMP (Linux 3.5 à Linux 4.7)" Le comportement des arrêts \fBPTRACE_EVENT_SECCOMP\fP et leur interaction avec les autres types d'arrêt ptrace a changé entre les versions du noyau. Nous documentons ici le comportement lors de leur introduction dans Linux\ 4.7 (inclus). Le comportement dans les versions postérieures du noyau est documenté dans la section suivante. .PP Un arrêt \fBPTRACE_EVENT_SECCOMP\fP se produit à chaque fois qu'une règle \fBSECCOMP_RET_TRACE\fP est déclenchée. Cela est indépendant de la méthode utilisée pour redémarrer l'appel système. En particulier, seccomp s'exécute toujours même si l'observé a été redémarré en utilisant \fBPTRACE_SYSEMU\fP et cet appel système est sauté sans condition. .PP .\" Les redémarrages à partir de cet arrêt se comporteront comme si l'arrêt s'était produit juste avant l'appel système en question. En particulier, tant \fBPTRACE_SYSCALL\fP que \fBPTRACE_SYSEMU\fP provoqueront normalement un arrêt\-entrée\-appel\-système ultérieur. Cependant, si après le \fBPTRACE_EVENT_SECCOMP\fP le numéro de l'appel système est négatif, l'arrêt\-entrée\-appel\-système et l'appel lui\-même seront tous deux sautés. Cela veut dire que si le numéro d'appel système est négatif après un \fBPTRACE_EVENT_SECCOMP\fP et si l'observé est redémarré en utilisant \fBPTRACE_SYSCALL\fP, le prochain arrêt observé sera un arrêt\-sortie\-appel\-système et non un arrêt\-entrée\-appel\-système qui comme on aurait pu s'y attendre. .SS "Arrêts PTRACE_EVENT_SECCOMP (depuis Linux\ 4.8)" .\" commit 93e35efb8de45393cf61ed07f7b407629bf698ea À partir de Linux 4.8, l'arrêt \fBPTRACE_EVENT_SECCOMP\fP a été réaménagé pour intervenir entre l'arrêt\-entrée\-appel\-système et l'arrêt\-sortie\-appel\-système. Remarquez que seccomp ne s'exécute plus (et aucun \fBPTRACE_EVENT_SECCOMP\fP ne sera renvoyé) si l'appel système est sauté du fait d'un \fBPTRACE_SYSEMU\fP. .PP Pratiquement, un arrêt \fBPTRACE_EVENT_SECCOMP\fP fonctionne comme un arrêt\-entrée\-appel\-système (à savoir que les reprises utilisant \fBPTRACE_SYSCALL\fP provoqueront des arrêts\-sortie\-appel\-système, le numéro de l'appel système peut être modifié et tous les registres modifiés sont visibles également à l'appel système à exécuter). Remarquez qu'il peut y avoir, sans obligation qu'il y ait déjà eu, un arrêt\-entrée\-appel\-système précédent. .PP .\" Après un arrêt \fBPTRACE_EVENT_SECCOMP\fP, seccomp sera réexécuté, avec une règle \fBSECCOMP_RET_TRACE\fP qui fonctionne désormais de la même manière que \fBSECCOMP_RET_ALLOW\fP. En particulier, cela veut dire que si les registres ne sont pas modifiés lors d'un arrêt \fBPTRACE_EVENT_SECCOMP\fP, l'appel système aura alors l'autorisation. .SS "Arrêts PTRACE_SINGLESTEP" .\" .\" FIXME . .\" document stops occurring with PTRACE_SINGLESTEP .\" [Les précisions sur ces types d'arrêts sont encore à documenter.] .SS "Commandes ptrace d'information et de redémarrage" La plupart des commandes ptrace (toutes sauf \fBPTRACE_ATTACH\fP, \fBPTRACE_SEIZE\fP, \fBPTRACE_TRACEME\fP, \fBPTRACE_INTERRUPT\fP et \fBPTRACE_KILL\fP) nécessitent que l'observé soit en arrêt\-ptrace, sinon il échoue avec \fBESRCH\fP. .PP Quand l'observé est en arrêt\-ptrace, l'observateur peut lire et écrire les donnés sur l'observé en utilisant les commandes d'information. Ces commandes laissent l'observé en état arrêté\-ptrace\ : .PP .in +4n .EX ptrace(PTRACE_PEEKTEXT/PEEKDATA/PEEKUSER, pid, addr, 0); ptrace(PTRACE_POKETEXT/POKEDATA/POKEUSER, pid, addr, long_val); ptrace(PTRACE_GETREGS/GETFPREGS, pid, 0, &struct); ptrace(PTRACE_SETREGS/SETFPREGS, pid, 0, &struct); ptrace(PTRACE_GETREGSET, pid, NT_foo, &iov); ptrace(PTRACE_SETREGSET, pid, NT_foo, &iov); ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo); ptrace(PTRACE_SETSIGINFO, pid, 0, &siginfo); ptrace(PTRACE_GETEVENTMSG, pid, 0, &long_var); ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags); .EE .in .PP Remarquez que certaines erreurs ne sont pas signalées. Par exemple, la configuration d'informations de signal (\fIsiginfo\fP) pourrait être sans effet pour certains arrêts\-ptrace, alors que l'appel pourrait\-être réussi (en renvoyant \fB0\fP et sans définir \fIerrno\fP)\ ; la demande de \fBPTRACE_GETEVENTMSG\fP pourrait réussir et renvoyer une quelconque valeur aléatoire si l'arrêt\-ptrace actuel n'est pas documenté comme renvoyant un message d'événement significatif. .PP L'appel .PP .in +4n .EX ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags); .EE .in .PP ne concerne qu'un observé. Les attributs actuels de l'observé sont remplacés. Les attributs sont hérités par les nouveaux observés créés et «\ attachés automatiquement\ » à l'aide d'options \fBPTRACE_O_TRACEFORK\fP, \fBPTRACE_O_TRACEVFORK\fP ou \fBPTRACE_O_TRACECLONE\fP actives. .PP Un autre groupe de commandes peut redémarrer l'observé arrêté\-ptrace. Ils sont de la forme\ : .PP .in +4n .EX ptrace(cmd, pid, 0, sig); .EE .in .PP où \fIcmd\fP est \fBPTRACE_CONT\fP, \fBPTRACE_LISTEN\fP, \fBPTRACE_DETACH\fP, \fBPTRACE_SYSCALL\fP, \fBPTRACE_SINGLESTEP\fP, \fBPTRACE_SYSEMU\fP ou \fBPTRACE_SYSEMU_SINGLESTEP\fP. Si l'observé est en arrêt\-distribution\-signal, \fIsig\fP est le signal à injecter (s'il est non nul). Sinon, \fIsig\fP pourrait être ignoré (lors du redémarrage d'un observé depuis un arrêt\-ptrace différent d'un arrêt\-distribution\-signal, il est conseillé de toujours passer 0 à \fIsig\fP). .SS "Attachement et détachement" Un thread peut être attaché à l'observateur en utilisant l'appel .PP .in +4n .EX ptrace(PTRACE_ATTACH, pid, 0, 0); .EE .in .PP ou .PP .in +4n .EX ptrace(PTRACE_SEIZE, pid, 0, PTRACE_O_flags); .EE .in .PP .\" .\" FIXME Describe how to attach to a thread which is already group-stopped. \fBPTRACE_ATTACH\fP envoie aussi \fBSIGSTOP\fP à ce thread. Si l'observateur veut que \fBSIGSTOP\fP soit sans effet, il doit le supprimer. Remarquez que si d'autres signaux sont envoyés en même temps à ce thread pendant l'attachement, l'observateur pourrait voir l'observé entrer en arrêt\-distribution\-signal avec d'autres signaux d'abord\ ! Ces signaux sont d'habitude réinjectés jusqu'à ce que \fBSIGSTOP\fP soit vu, puis l'injection \fBSIGSTOP\fP est supprimée. Le bogue de conception ici est qu'un attachement ptrace et un \fBSIGSTOP\fP distribués en même temps peuvent entrer en compétition et le \fBSIGSTOP\fP risque d'être perdu. .PP Puisque l'attachement envoie \fBSIGSTOP\fP et que l'observateur le supprime normalement, cela risque de forcer le retour d'un \fBEINTR\fP perdu de l'appel système en cours d'exécution dans l'observé, tel que c'est décrit dans la section \fBInjection et suppression de signal\fP. .PP Depuis Linux\ 3.4, \fBPTRACE_SEIZE\fP peut être utilisé à la place de \fBPTRACE_ATTACH\fP. \fBPTRACE_SEIZE\fP n'arrête pas le processus attaché. Si vous devez l'arrêter après attachement (ou à n'importe quel autre moment) sans lui envoyer de signal du tout, utilisez la commande \fBPTRACE_INTERRUPT\fP. .PP La requête .PP .in +4n .EX ptrace(PTRACE_TRACEME, 0, 0, 0); .EE .in .PP transforme le thread appelant en observé. L'appel continue d'être exécuté (n'entre pas en arrêt\-ptrace). \fBPTRACE_TRACEME\fP est habituellement suivi avec .PP .in +4n .EX raise(SIGSTOP); .EE .in .PP et permet au parent (qui est maintenant l'observateur) de respecter l'arrêt\-distribution\-signal. .PP Si les options \fBPTRACE_O_TRACEFORK\fP, \fBPTRACE_O_TRACEVFORK\fP ou \fBPTRACE_O_TRACECLONE\fP font effet, alors les enfants respectivement créés par \fBvfork\fP(2) ou \fBclone\fP(2) avec l'attribut \fBCLONE_VFORK\fP, \fBfork\fP(2) ou \fBclone\fP(2) avec le signal de sortie configuré à \fBSIGCHLD\fP, et d'autres sortes de \fBclone\fP(2), sont automatiquement attachés au même observateur qui à suivi leur parent. \fBSIGSTOP\fP est distribué aux enfants, les forçant à entrer en arrêt\-distribution\-signal après être sortis de l'appel système qu'ils ont créé. .PP Le détachement de l'observé est réalisé par\ : .PP .in +4n .EX ptrace(PTRACE_DETACH, pid, 0, sig); .EE .in .PP \fBPTRACE_DETACH\fP est une opération de redémarrage\ ; par conséquent elle nécessite que l'observé soit en arrêt\-ptrace. Si l'observé est en arrêt\-distribution\-signal, un signal peut être injecté. Sinon, le paramètre \fIsig\fP pourrait être silencieusement ignoré. .PP .\" FIXME Describe how to detach from a group-stopped tracee so that it .\" doesn't run, but continues to wait for SIGCONT. Si l'observé est en cours d'exécution quand l'observateur veut le détacher, la solution habituelle est d'envoyer \fBSIGSTOP\fP (en utilisant \fBtgkill\fP(2), pour s'assurer qu'il va au bon thread), d'attendre que l'observé s'arrête en arrêt\-distribution\-signal pour \fBSIGSTOP\fP et ensuite de le détacher (en supprimant l'injection \fBSIGSTOP\fP). Un bogue de conception est que l'observé pourrait entrer dans d'autres arrêts\-ptrace et avoir besoin d'être redémarré et attendre encore, jusqu'à ce que \fBSIGSTOP\fP soit vu. Encore une autre complication est de s'assurer que l'observé n'est pas déjà arrêté\-ptrace, parce qu'aucune distribution de signal n'arrive tant qu'il l'est —\ pas même \fBSIGSTOP\fP. .PP Si l'observateur meurt, tous les observés sont automatiquement détachés et redémarrés, sauf s'il étaient en arrêt\-groupe. Le gestion de redémarrage depuis un arrêt\-groupe est en ce moment dysfonctionnelle, mais le comportement «\ prévu\ »\ est de laisser les observés arrêtés et d'attendre un \fBSIGCONT\fP. Si l'observé est redémarré depuis un arrêt\-distribution\-signal, le signal en attente est injecté. .SS "execve(2) sous ptrace" .\" clone(2) CLONE_THREAD says: .\" If any of the threads in a thread group performs an execve(2), .\" then all threads other than the thread group leader are terminated, .\" and the new program is executed in the thread group leader. .\" .\" In Linux 3.1 sources, see fs/exec.c::de_thread() Quand un thread de processus multithreadé appelle \fBexecve\fP(2), le noyau détruit tous les autres threads du processus, et réinitialise l'identifiant de thread du thread exécuté à l'identifiant de groupe de threads (PID) (ou, pour le présenter autrement, quand un processus multithreadé fait un \fBexecve\fP(2), à la fin de l'appel, il apparaît comme si l'\fBexecve\fP(2) s'était appliqué au leader de groupe de threads, quelque soit le thread qui a fait \fBexecve\fP(2)). Cette réinitialisation de l'identifiant de thread semble est très déroutante pour les observateurs. .IP \- 3 Tous les autres threads s'arrêtent en arrêt \fBPTRACE_EVENT_EXIT\fP, si l'option \fBPTRACE_O_TRACEEXIT\fP était activée. Alors tous les autres threads sauf le leader de groupe de threads signalent leur mort comme s'il s'étaient terminés par l'intermédiaire de \fB_exit\fP(2) avec un code de retour \fB0\fP. .IP \- L'observé en cours d'exécution modifie son identifiant de thread pendant qu'il est dans l'\fBexecve\fP(2) (rappelez\-vous que, sous ptrace, le «\ pid\ » renvoyé par \fBwaitpid\fP(2) ou fourni dans les appels ptrace, est l'identifiant de thread de l'observé). Ainsi, l'identifiant de thread de l'observé est réinitialisé pour être le même que son identifiant de processus (PID), qui est le même que l'identifiant de thread du leader de groupe de threads. .IP \- Ensuite un arrêt \fBPTRACE_EVENT_EXEC\fP arrive, si l'option \fBPTRACE_O_TRACEEXEC\fP était activée. .IP \- Si le leader de groupe de threads a signalé son arrêt \fBPTRACE_EVENT_EXIT\fP pendant ce temps, le leader de thread mort à l'air de «\ revenir de nulle part\ » du point de vue de l'observateur (remarque\ : le leader de groupe de threads ne signale pas sa mort à l'aide de \fIWIFEXITED(status)\fP tant qu'au moins un autre thread est en vie. Cela enlève la possibilité à l'observateur de le voir mourir puis réapparaître). Si le leader de groupe de threads était encore en vie, cela pourrait être vu par l'observateur comme si le leader de groupe revenait d'un autre appel système que celui dans lequel il était entré, ou même «\ revenait d'un appel système même s'il n'y avait pas d'appel système\ ». Si le leader de groupe de threads n'était pas suivi (ou était suivi par un autre observateur), alors pendant \fBexecve\fP(2) il apparaîtra comme s'il était devenu un observé de l'observateur de l'observé en cours d'exécution. .PP Tous les effets précédents sont des artifices de la modification d'identifiant de thread de l'observé. .PP L'option \fBPTRACE_O_TRACEEXEC\fP est l'outil conseillé pour s'occuper de cette situation. D'abord, elle active l'arrêt \fBPTRACE_EVENT_EXEC\fP, qui arrive avant le retour d'\fBexecve\fP(2). Dans cet arrêt, l'observateur peut utiliser \fBPTRACE_GETEVENTMSG\fP pour récupérer l'ancien identifiant de thread de l'observé (cette fonctionnalité a été introduite avec Linux\ 3.0). Ensuite, l'option \fBPTRACE_O_TRACEEXEC\fP désactive la création obsolète de \fBSIGTRAP\fP dans \fBexecve\fP(2). .PP Quand l'observé reçoit une notification d'arrêt \fBPTRACE_EVENT_EXEC\fP, il est garanti qu'à part cet observé et le leader de groupe de threads, aucun autre thread du processus n'est en vie. .PP Lors de la réception d'une notification d'arrêt \fBPTRACE_EVENT_EXEC\fP, l'observateur devrait nettoyer toutes ses structures de données internes décrivant les threads de ce processus et ne garder qu'une seule structure de données —\ celle qui décrit l'unique observé en cours d'exécution, avec .PP .in +4n .EX identifiant de thread == identifiant de groupe de threads == identifiant de processus. .EE .in .PP Par exemple, soient deux threads qui appellent \fBexecve\fP(2) en même temps\ : .PP .nf *** arrêt\-entrée\-appel\-système obtenu dans le thread 1 : ** PID1 execve("/bin/truc", "truc" *** PTRACE_SYSCALL émis pour le thread 1 ** *** arrêt\-entrée\-appel\-système obtenu dans le thread 2 : ** PID2 execve("/bin/bidule", "bidule" *** PTRACE_SYSCALL émis pour le thread 2 ** *** PTRACE_EVENT_EXEC obtenu pour PID0, PTRACE_SYSCALL émis ** *** arrêt\-sortie\-appel\-système obtenu pour PID0 : ** PID0 <… retour d'execve> ) = 0 .fi .PP Si l'option \fBPTRACE_O_TRACEEXEC\fP n'est \fIpas\fP effective pour l'observé en cours d'exécution et si l'observé a été \fBPTRACE_ATTACH\fPé et non \fBPTRACE_SEIZE\fPé, le noyau distribue un \fBSIGTRAP\fP supplémentaire à l'observé après le retour d'\fBexecve\fP(2). C'est un signal normal (similaire à celui qui peut être créé par \fIkill \-TRAP\fP), pas une sorte spéciale d'arrêt\-ptrace. L'utilisation de \fBPTRACE_GETSIGINFO\fP pour ce signal renvoie \fIsi_code\fP configuré à \fB0\fP (\fISI_USER\fP). Ce signal pourrait être bloqué par un masque de signal et pourrait ainsi être distribué (bien) plus tard. .PP Normalement, l'observateur (par exemple \fBstrace\fP(1)) ne voudrait pas montrer ce signal \fBSIGTRAP\fP supplémentaire postérieur à \fBexecve\fP à l'utilisateur, et voudrait supprimer sa distribution à l'observé (si \fBSIGTRAP\fP est configuré à \fBSIG_DFL\fP, c'est un signal tueur). Cependant, déterminer \fIquel\fP est le \fBSIGTRAP\fP à supprimer n'est pas simple. La configuration de l'option \fBPTRACE_O_TRACEEXEC\fP ou l'utilisation de \fBPTRACE_SEIZE\fP et par conséquent la suppression du \fBSIGTRAP\fP supplémentaire est l'approche conseillée. .SS "Vrai parent" L'interface de programmation de ptrace utilise (parfois mal) la norme UNIX de signalement de parent ou enfant par l'intermédiaire de \fBwaitpid\fP(2). Cela a régulièrement forcé le vrai parent du processus à arrêter de recevoir plusieurs sortes de notifications de \fBwaitpid\fP(2) quand le processus enfant est suivi par un autre processus. .PP De nombreux bogues de ce type ont été corrigés, mais il en reste encore beaucoup dans Linux\ 2.6.38. Consultez la section \fBBOGUES\fP ci dessous. .PP Depuis Linux\ 2.6.38, ce qui suit est censé fonctionner correctement\ : .IP \- 3 l'exécution ou la mort par signal sont d'abord signalées à l'observateur, puis, quand l'observateur consomme le résultat de \fBwaitpid\fP(2), au vrai parent (au vrai parent seulement quand l'intégralité du processus multithreadé se termine). Si l'observateur et le vrai parent sont le même processus, le signalement n'est envoyé qu'une fois. .SH "VALEUR RENVOYÉE" En cas de succès, la requête \fBPTRACE_PEEK*\fP renvoie les données demandées (mais consultez les NOTES), la requête \fBPTRACE_SECCOMP_GET_FILTER\fP renvoie le nombre d'instructions du programme BPF, la requête \fBPTRACE_GET_SYSCALL_INFO\fP renvoie le nombre d'octets disponibles disponible pour être écrits par le noyau, alors que les autres requêtes renvoient zéro. .PP En cas d'erreur, toutes les requêtes renvoient \fB\-1\fP et \fIerrno\fP est défini pour indiquer l'erreur. Comme la valeur renvoyée par une requête \fBPTRACE_PEEK*\fP peut légitimement être \fB\-1\fP, l'appelant doit effacer \fIerrno\fP avant l'appel, et ensuite le vérifier pour savoir si une erreur s'est produite. .SH ERREURS .TP \fBEBUSY\fP (i386 seulement) Une erreur est survenue lors de l'allocation ou de la libération d'un registre de débogage. .TP \fBEFAULT\fP Tentative de lire ou écrire dans une zone mémoire non valable de l'observateur ou de l'observé, probablement parce que la zone n'était pas projetée ou accessible. Malheureusement sous Linux, certaines variantes de cette erreur déclencheront \fBEIO\fP ou \fBEFAULT\fP plus ou moins arbitrairement. .TP \fBEINVAL\fP Tentative d'utiliser une option non valable. .TP \fBEIO\fP La requête \fIrequest\fP n'est pas valable ou une tentative de lecture ou d'écriture dans une zone non valable de mémoire de l'observateur ou de l'observé a eu lieu. Un problème d'alignement a aussi pu survenir sur une frontière de mot, ou une tentative de redémarrage en envoyant un signal non valable. .TP \fBEPERM\fP Le processus indiqué ne peut pas être suivi. Cela peut être dû à un manque de privilège de l'observateur (la capacité nécessaire est \fBCAP_SYS_PTRACE\fP). Les processus non privilégiés ne peuvent pas suivre les processus auxquels ils ne peuvent envoyer de signal, ou ceux qui s'exécutent Set\-UID/Set\-GID, pour des raisons évidentes. En outre, le processus visé peut être déjà suivi, ou (avant Linux\ 2.6.26) être \fBinit\fP(8) (le processus numéro\ 1). .TP \fBESRCH\fP Le processus indiqué n'existe pas, ou n'est pas suivi par l'appelant, ou n'est pas arrêté (pour les requêtes qui ont besoin d'un observé arrêté). .SH STANDARDS Aucun. .SH HISTORIQUE SVr4, 4.3BSD. .PP .\" See commit 00cd5c37afd5f431ac186dd131705048c0a11fdb Avant Linux\ 2.6.26, \fBinit\fP(8), le processus numéro\ 1, ne peut pas être suivi. .SH NOTES Bien que les arguments de \fBptrace\fP() soient interprétés comme dans le prototype donné, la bibliothèque glibc déclare \fBptrace\fP comme une fonction variadique où seul l'argument \fIrequest\fP est corrigé. Il vaut mieux toujours fournir quatre arguments, même si l'opération demandée ne les utilise pas, en configurant les arguments non utilisés ou ignorés à \fI0L\fP ou \fI(void\ *)\ 0\fP. .PP Le parent d'observés reste observateur même s'il appelle \fBexecve\fP(2). .PP .\" See http://lkml.org/lkml/2008/5/8/375 La disposition du contenu de la mémoire et de la zone USER dépendent du système d'exploitation et de l'architecture. Le décalage fourni et les données renvoyées peuvent ne pas correspondre entièrement avec la définition d'une structure \fIstruct user\fP. .PP La taille d'un mot («\ word\ ») est déterminée par la version du système d'exploitation (par exemple 32\ bits pour Linux 32\ bits). .PP .\" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\" Cette page documente le fonctionnement actuel de \fBptrace\fP() sous Linux. Celui\-ci peut varier significativement d'autres types d'UNIX. De toute façon, l'utilisation de \fBptrace\fP() dépend fortement de l'architecture et du système d'exploitation. .SS "Vérification du mode d'accès ptrace" Divers endroits de l'API de l'espace utilisateur du noyau (pas seulement les opérations \fBptrace\fP()) exigent ce qu'on appelle des «\ vérifications de mode d'accès ptrace\ », dont le résultat détermine si une opération est autorisée (ou, dans certains cas, fait renvoyer à l'opération «\ read\ » des données nettoyées). Ces vérifications sont effectuées dans les cas où un processus peut accéder à des informations sensibles concernant un autre processus ou modifier son état. Les vérifications s'opèrent sur la base de facteurs tels que les droits et les capacités des deux processus, le fait que le processus «\ cible\ » puisse générer un fichier core, et des résultats des vérifications effectuées par un module de sécurité Linux activé (LSM) (par exemple SELinux, Yama ou Smack) et par le LSM commoncap (qui est toujours appelé). .PP .\" commit 006ebb40d3d65338bd74abb03b945f8d60e362bd Avant Linux\ 2.6.27, toutes les vérifications d'accès étaient d'un seul type. Depuis Linux\ 2.6.27, on distingue deux niveaux de modes d'accès\ : .TP \fBPTRACE_MODE_READ\fP Pour les opérations «\ read\ » ou d'autres moins dangereuses telles que\ : \fBget_robust_list\fP(2)\ ; \fBkcmp\fP(2)\ ; la lecture de \fI/proc/\fPpid\fI/auxv\fP, \fI/proc/\fPpid\fI/environ\fP ou de \fI/proc/\fPpid\fI/stat\fP\ ; ou le \fBreadlink\fP(2) d'un fichier \fI/proc/\fPpid\fI/ns/*\fP. .TP \fBPTRACE_MODE_ATTACH\fP .\" .\" Regarding the above description of the distinction between .\" PTRACE_MODE_READ and PTRACE_MODE_ATTACH, Stephen Smalley notes: .\" .\" That was the intent when the distinction was introduced, but it doesn't .\" appear to have been properly maintained, e.g. there is now a common .\" helper lock_trace() that is used for .\" /proc/pid/{stack,syscall,personality} but checks PTRACE_MODE_ATTACH, and .\" PTRACE_MODE_ATTACH is also used in timerslack_ns_write/show(). Likely .\" should review and make them consistent. There was also some debate .\" about proper handling of /proc/pid/fd. Arguably that one might belong .\" back in the _ATTACH camp. .\" Pour les opérations «\ write\ » ou d'autres plus dangereuses telles que\ : le rattachement de ptrace (\fBPTRACE_ATTACH\fP) à un autre processus ou un appel \fBprocess_vm_writev\fP(2) (\fBPTRACE_MODE_ATTACH\fP était celui par défaut avant Linux\ 2.6.27). .PP .\" commit caaee6234d05a58c5b4d05e7bf766131b810a657 Depuis Linux 4.5, les vérifications de mode d'accès ci\-dessus sont combinées (opération OU) avec un ou plusieurs des modificateurs suivants\ : .TP \fBPTRACE_MODE_FSCREDS\fP Utiliser l'identifiant de groupe ou d’utilisateur du système de fichiers de l'appelant (voir \fBcredentials\fP(7)) ou les capacités effectives pour les vérifications LSM. .TP \fBPTRACE_MODE_REALCREDS\fP Utiliser l'identifiant de groupe ou d’utilisateur réel de l'appelant ou les capacités autorisées pour les vérifications LSM. C'était l'action par défaut avant Linux\ 4.5. .PP La combinaison d'un des modificateurs de droits avec un des modes d'accès ci\-dessus étant classique, certaines macros sont définies dans les sources du noyau pour les combinaisons\ : .TP \fBPTRACE_MODE_READ_FSCREDS\fP Définie en tant que \fBPTRACE_MODE_READ | PTRACE_MODE_FSCREDS\fP. .TP \fBPTRACE_MODE_READ_REALCREDS\fP Définie en tant que \fBPTRACE_MODE_READ | PTRACE_MODE_REALCREDS\fP. .TP \fBPTRACE_MODE_ATTACH_FSCREDS\fP Définie en tant que \fBPTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS\fP. .TP \fBPTRACE_MODE_ATTACH_REALCREDS\fP Définie en tant que \fBPTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS\fP. .PP Un modificateur supplémentaire peut être lié (opération OU) au mode d'accès\ : .TP \fBPTRACE_MODE_NOAUDIT\fP (depuis Linux\ 3.3) .\" commit 69f594a38967f4540ce7a29b3fd214e68a8330bd .\" Just for /proc/pid/stat Ne pas effectuer la vérification de ce mode d'accès. Ce modificateur est utilisé pour les vérifications de mode d'accès ptrace (telles que celles faites lors de la lecture de \fI/proc/\fPpid\fI/stat\fP) qui filtrent ou nettoient la sortie au lieu de renvoyer une erreur à l'appelant. Dans ces cas, l'accès au fichier n'est pas une violation de sécurité et il n'y aucune raison de générer un enregistrement de l'évaluation de la sécurité. Ce modificateur supprime la génération d'un tel enregistrement pour cette vérification d'accès particulière. .PP Remarquez que toutes les constantes \fBPTRACE_MODE_*\fP décrites dans cette sous\-section sont internes au noyau et invisibles à l'espace utilisateur. Le nom des constantes est mentionné ici pour identifier les différents types de vérification des modes d'accès ptrace effectuées pour divers appels système et divers accès à des pseudofichiers (comme dans \fI/proc\fP). Ces noms sont utilisés dans d'autres pages de manuel pour fournir un raccourci simple d'identification des vérifications du noyau. .PP L'algorithme utilisé pour la vérification des modes d'accès ptrace détermine si le processus appelant est autorisé à effectuer l'action correspondante sur le processus cible (pour l'ouverture des fichiers \fI/proc/\fPpid, le «\ processus appelant\ » est celui qui ouvre le fichier et le processus dont le PID correspond est le «\ processus cible\ »). L’algorithme est comme suit\ : .IP (1) 5 Si le thread appelant et cible sont dans le même groupe de threads, l'accès est toujours autorisé. .IP (2) Si le mode d'accès indique \fBPTRACE_MODE_FSCREDS\fP, lors de la vérification de la prochaine étape, utiliser l'identifiant d'utilisateur et de groupe du système de fichiers appelant (comme indiqué dans \fBcredentials\fP(7), les identifiants d'utilisateur et de groupe du système de fichiers ont presque toujours la même valeur que les identifiants effectifs correspondant). .IP Sinon le mode d'accès indique \fBPTRACE_MODE_REALCREDS\fP, donc utiliser l'identifiant d'utilisateur et de groupe réels de l'appelant lors des vérifications de la prochaine étape (la plupart des API qui vérifient les identifiants d’utilisateur et de groupe utilisent les identifiants effectifs. Pour des raisons historiques, la vérification \fBPTRACE_MODE_REALCREDS\fP utilise plutôt ceux réels). .IP (3) Interdire l'accès si \fIrien\fP de ce qui suit n'est vrai\ : .RS .IP \- 3 Les identifiants utilisateur réel, effectif et défini de la cible correspondent à l'identifiant utilisateur de l'appelant \fIet\fP les identifiants réels, effectifs et définis de groupe de la cible correspondent à ceux de groupe de l'appelant. .IP \- L'appelant a la capacité \fBCAP_SYS_PTRACE\fP dans l'espace de noms utilisateur de la cible. .RE .IP (4) Interdire l'accès si l'attribut «\ dumpable\ » du processus cible a une autre valeur que \fB1\fP (\fBSUID_DUMP_USER\fP\ ; voir le point sur \fBPR_SET_DUMPABLE\fP dans \fBprctl\fP(2)) et l'appelant n'a pas la capacité \fBCAP_SYS_PTRACE\fP dans l'espace de noms de l'utilisateur du processus cible. .IP (5) .\" (in cap_ptrace_access_check()): L'interface \fIsecurity_ptrace_access_check\fP() du LSM du noyau est appelée pour voir si l'accès ptrace est autorisé. Le résultat dépend des LSM. L'implémentation de cette interface dans le LSM commoncap suit les étapes suivantes\ : .RS .IP (5.1) 7 Si le mode d'accès comprend \fBPTRACE_MODE_FSCREDS\fP, utiliser l’ensemble des capacités \fIeffectives\fP de l'appelant dans la prochaine vérification\ ; sinon (si le mode d'accès indique \fBPTRACE_MODE_REALCREDS\fP), utiliser l’ensemble des capacités \fIautorisées\fP de l'appelant. .IP (5.2) Interdire l'accès si \fIrien\fP de ce qui suit n'est vrai\ : .RS .IP \- 3 Les processus appelant et cible sont dans le même espace de noms utilisateur et les capacités de l'appelant sont un surensemble des capacités \fIautorisées\fP du processus cible. .IP \- L'appelant a la capacité \fBCAP_SYS_PTRACE\fP dans l'espace de noms utilisateur du processus cible. .RE .IP Remarquez que le LSM commoncap ne fait pas de différence entre \fBPTRACE_MODE_READ\fP et \fBPTRACE_MODE_ATTACH\fP. .RE .IP (6) .\" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\" Si l'accès n'a pas été interdit par une étape précédente, il est autorisé. .SS /proc/sys/kernel/yama/ptrace_scope .\" commit 2d514487faf188938a4ee4fb3464eeecfbdcf8eb Sur des systèmes ayant un Yama Linux Security Module (LSM) installé (donc si le noyau a été configuré avec \fBCONFIG_SECURITY_YAMA\fP), le fichier \fI/proc/sys/kernel/yama/ptrace_scope\fP (disponible depuis Linux\ 3.4) peut être utilisé pour restreindre la possibilité d'observer un processus avec \fBptrace\fP() (et ainsi, celle d'utiliser des outils tels que \fBstrace\fP(1) et \fBgdb\fP(1)). Le but de telles restrictions est d'empêcher des attaques en cascade par lesquelles un processus infecté peut s'attacher avec un ptrace à d'autres processus sensibles (comme un agent GPG ou une session SSH) appartenant à l'utilisateur, afin d'obtenir d'autres droits qui pourraient exister en mémoire et ainsi, élargir l'objectif de l'attaque. .PP Plus précisément, le Yama LSM limite deux types d'opérations\ : .IP \- 3 Toute opération qui effectue une vérification \fBPTRACE_MODE_ATTACH\fP de mode d'accès (par exemple, \fBPTRACE_ATTACH\fP de \fBptrace\fP(), voir le point sur les «\ vérifications de mode d'accès ptrace\ » ci\-dessus). .IP \- \fBPTRACE_TRACEME\fP \fBptrace\fP(). .PP Un processus ayant la capacité \fBCAP_SYS_PTRACE\fP peut mettre à jour le fichier \fI/proc/sys/kernel/yama/ptrace_scope\fP avec une ou plusieurs des valeurs suivantes\ : .TP \fB0\fP (droits ptrace «\ classiques\ ») Aucune restriction supplémentaire sur les opérations qui effectuent des vérifications \fBPTRACE_MODE_ATTACH\fP (au\-delà de celles imposées par le LSM commoncap et les autres). .IP L'utilisation de \fBPTRACE_TRACEME\fP ne change pas. .TP \fB1\fP («\ ptrace restreint\ » (valeur par défaut) Lors d'une opération qui exige une vérification \fBPTRACE_MODE_ATTACH\fP, le processus appelant doit avoir soit la capacité \fBCAP_SYS_PTRACE\fP dans l'espace de noms utilisateur du processus cible, soit une relation prédéfinie avec le processus cible. Par défaut, la relation prédéfinie est que le processus cible doit être un descendant de l'appelant. .IP .\" commit 90bb766440f2147486a2acc3e793d7b8348b0c22 Un processus cible peut utiliser l'opération \fBPR_SET_PTRACER\fP de \fBprctl\fP(2) pour déclarer un PID supplémentaire autorisé à effectuer des opérations \fBPTRACE_MODE_ATTACH\fP sur la cible. Voir le fichier \fIDocumentation/admin\-guide/LSM/Yama.rst\fP des sources du noyau (ou \fIDocumentation/security/Yama.txt\fP avant Linux\ 4.13) pour plus de détails. .IP L'utilisation de \fBPTRACE_TRACEME\fP ne change pas. .TP \fB2\fP (attachement «\ admin\-only\ ») Seuls les processus ayant la capacité \fBCAP_SYS_PTRACE\fP dans l'espace de noms de l'utilisateur du processus cible peuvent effectuer des opérations \fBPTRACE_MODE_ATTACH\fP ou observer les enfants qui utilisent \fBPTRACE_TRACEME\fP. .TP \fB3\fP («\ pas d'attachement\ ») Aucun processus ne peut effectuer d'opération \fBPTRACE_MODE_ATTACH\fP ou observer les enfants qui utilisent \fBPTRACE_TRACEME\fP. .IP Une fois que cette valeur a été écrite dans le fichier, elle ne peut pas être modifiée. .PP .\" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\" Par rapport aux valeurs \fB1\fP et \fB2\fP, remarquez que la création d'un nouvel espace de noms utilisateur supprime de fait la protection apportée par Yama. Cela parce qu'un processus dans l'espace de noms de l'utilisateur parent dont l'identifiant utilisateur effectif correspond à celui de l'espace de noms enfant a toutes les capacités (y compris \fBCAP_SYS_PTRACE\fP) lorsqu'il effectue des opérations dans l'espace de noms utilisateur de l'enfant (et les descendants supprimés plus tard de cet espace de noms). Par conséquent, quand un processus essaie d'utiliser les espaces de noms utilisateur pour s'isoler lui\-même, il affaiblit à son insu les protections apportées par le Yama LSM. .SS "Différences entre bibliothèque C et noyau" L'interface de programmation de l'appel système est différente pour les requêtes \fBPTRACE_PEEKTEXT\fP, \fBPTRACE_PEEKDATA\fP et \fBPTRACE_PEEKUSER\fP\ : elles stockent le résultat à l’adresse indiquée par le paramètre \fIdata\fP, et la valeur de retour est l’attribut d’erreur. La fonction glibc encapsulant cet appel fournit une interface détaillée dans la section \fBDESCRIPTION\fP ci\-dessus, et le résultat qu'elle renvoie est le résultat de l'appel système. .SH BOGUES Sur les machines ayant des en\-têtes du noyau Linux\ 2.6, \fBPTRACE_SETOPTIONS\fP est déclaré avec une valeur différente de celle de Linux\ 2.4. De ce fait, les applications compilées avec des en\-têtes du noyau\ Linux\ 2.6 ne peuvent pas s'exécuter sous Linux\ 2.4. Il est possible de contourner cette difficulté en redéfinissant \fBPTRACE_SETOPTIONS\fP à \fBPTRACE_OLDSETOPTIONS\fP, si cette dernière constante est définie. .PP Les notifications d'arrêt\-groupe sont envoyées à l'observateur, mais pas au vrai parent. C'était encore vrai sur 2.6.38.6. .PP .\" Note from Denys Vlasenko: .\" Here "exits" means any kind of death - _exit, exit_group, .\" signal death. Signal death and exit_group cases are trivial, .\" though: since signal death and exit_group kill all other threads .\" too, "until all other threads exit" thing happens rather soon .\" in these cases. Therefore, only _exit presents observably .\" puzzling behavior to ptrace users: thread leader _exit's, .\" but WIFEXITED isn't reported! We are trying to explain here .\" why it is so. .\" FIXME . need to test/verify this scenario Si un leader de groupe de threads est suivi et existe en appelant \fB_exit\fP(2), un arrêt \fBPTRACE_EVENT_EXIT\fP lui arrivera (si réclamé), mais la notification \fBWIFEXITED\fP suivante ne sera pas distribuée avant la fin de tous les autres threads. Comme expliqué précédemment, si un des autres threads appelle \fBexecve\fP(2), la mort du leader de groupe de threads ne sera \fIjamais\fP signalée. Si le thread exécuté n'est pas suivi par cet observateur, l'observé ne saura jamais qu'\fBexecve\fP(2) est arrivé. Un contournement possible est de \fBPTRACE_DETACH\fPer le leader de groupe de threads au lieu de le redémarrer dans ce cas. C'était encore vrai sur 2.6.38.6. .PP Un signal \fBSIGKILL\fP pourrait encore provoquer un arrêt \fBPTRACE_EVENT_EXIT\fP avant une véritable mort du signal. Cela pourrait évoluer à l'avenir. \fBSIGKILL\fP est supposé tuer immédiatement les tâches même sous ptrace. C'était encore vrai sur Linux\ 3.13. .PP Certains appels système renvoient \fBEINTR\fP si un signal a été envoyé à l'observé, mais que la distribution a été supprimée par l'observateur (c'est une opération tout à fait caractéristique\ : elle est normalement réalisée par les débogueurs sur tous les attachements, afin de ne pas introduire de \fBSIGSTOP\fP défectueux). Depuis Linux\ 3.2.9, les appels système suivants sont concernés (cette liste est sans doute incomplète)\ : \fBepoll_wait\fP(2) et \fBread\fP(2) depuis un descripteur de fichier \fBinotify\fP(7). Le symptôme classique de ce bogue est qu'en attachant à un processus quiescent avec la commande .PP .in +4n .EX strace \-p .EE .in .PP alors, au lieu de la ligne de sortie habituelle attendue comme .PP .in +4n .EX restart_syscall(<... reprise de l'appel interrompu ...>_ .EE .in .PP ou .PP .in +4n .EX select(6, [5], NULL, [5], NULL_ .EE .in .PP («\ _\ » indique la position du curseur), plusieurs lignes sont affichées. Par exemple\ : .PP .in +4n .EX clock_gettime(CLOCK_MONOTONIC, {15370, 690928118}) = 0 epoll_wait(4,_ .EE .in .PP Ce qui n'est pas visible ici est que le processus a été bloqué dans \fBepoll_wait\fP(2) avant que \fBstrace\fP(1) ne s'y soit attaché. L'attachement a forcé \fBepoll_wait\fP(2) à revenir dans l'espace utilisateur avec l'erreur \fBEINTR\fP. Dans ce cas particulier, le programme a réagit à \fBEINTR\fP en vérifiant l'heure actuelle et en exécutant encore \fBepoll_wait\fP(2) (les programmes qui ne s'attendent pas à de telles erreurs \fBEINTR\fP «\ perdue\ » risquent de se comporter de façon inattendue sur une attache \fBstrace\fP(1)). .PP Contrairement aux règles normales, l'enveloppe de la glibc pour \fBptrace\fP() peut positionner \fIerrno\fP sur zéro. .SH "VOIR AUSSI" \fBgdb\fP(1), \fBltrace\fP(1), \fBstrace\fP(1), \fBclone\fP(2), \fBexecve\fP(2), \fBfork\fP(2), \fBgettid\fP(2), \fBprctl\fP(2), \fBseccomp\fP(2), \fBsigaction\fP(2), \fBtgkill\fP(2), \fBvfork\fP(2), \fBwaitpid\fP(2), \fBexec\fP(3), \fBcapabilities\fP(7), \fBsignal\fP(7) .PP .SH TRADUCTION La traduction française de cette page de manuel a été créée par Christophe Blaess , Stéphan Rafin , Thierry Vignaud , François Micaux, Alain Portal , Jean-Philippe Guérard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas François , Florentin Duneau , Simon Paillard , Denis Barbier , David Prévot et Jean-Philippe MENGUAL . .PP Cette traduction est une documentation libre ; veuillez vous reporter à la .UR https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3 .UE concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. .PP Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à .MT debian-l10n-french@lists.debian.org .ME .