pkeys(7) Miscellaneous Information Manual pkeys(7) NOM pkeys - Apercu des cles de protection de la memoire DESCRIPTION Les cles de protection de la memoire (Memory Protection Keys -- pkeys) sont une extension des permissions de la memoire basees sur les pages. Les permissions normales de page necessitent des appels systeme couteux et des invalidations du TLB (Translation Lookaside Buffer) lors de modifications de permission. Les cles de protection de la memoire fournissent un mecanisme pour changer les protections sans avoir besoin de modifier la table des pages lors de chaque modification de permission. Pour utiliser pkeys, le logiciel doit d'abord << etiqueter >> une page dans la table des pages avec une pkey. Une fois cette etiquette posee, une application a seulement a changer le contenu d'un registre pour retirer l'acces en ecriture ou tous les acces a une page etiquetee. Les cles de protection de la memoire fonctionnent en conjonction avec les permissions PROT_READ, PROT_WRITE et PROT_EXEC existantes passees aux appels systeme tels que mprotect(2) et mmap(2), mais agissent toujours pour restreindre encore plus ces mecanismes de permission traditionnels. Si un processus realise un acces qui enfreint les restrictions de pkey, il recoit un signal SIGSEGV. Consultez sigaction(2) pour des details sur l'information disponible avec ce signal. Pour utiliser la fonctionnalite de pkeys, le processeur doit la prendre en charge et le noyau doit contenir une prise en charge pour la fonctionnalite d'un processeur donne. Au tout debut de 2016, seuls les processeurs x86 d'Intel a venir etaient pris en charge et ceux-ci geraient 16 cles de protection de la memoire pour chaque processus. Cependant, la pkey 0 est utilisee comme cle par defaut, donc un maximum de 15 sont disponibles pour une utilisation effective d'application. La cle par defaut est affectee a n'importe quelle region de la memoire pour laquelle une pkey n'a pas ete assignee explicitement a l'aide de pkey_mprotect(2). Les cles de protection ont la capacite d'ajouter une couche de securite et de fiabilite aux applications, mais elles n'ont pas ete concues principalement pour une fonctionnalite de securite. Par exemple, WRPKRU est une instruction entierement non privilegiee, aussi les pkeys sont inutiles dans tous les cas ou un attaquant controle le registre PKRU ou peut executer des instructions arbitraires. Les applications doivent etre tres precautionneuses pour assurer de ne pas faire << fuiter >> leurs cles de protection. Par exemple, avant d'appeler pkey_free(2), l'application doit etre sure qu'aucune memoire a cette pkey assignee. Si l'application laisse la pkey liberee assignee, un prochain utilisateur de cette pkey peut par inadvertance modifier les permissions d'une structure de donnees etrangere, pouvant impacter la securite ou la stabilite. Le noyau permet actuellement aux pkeys en cours d'avoir pkey_free(2) appelee sur elles, car cela pourrait avoir des implications de performance de processeur ou de memoire pour realiser des verifications supplementaires necessaires pour desactiver cet appel. L'implementation des verifications necessaires est laissee aux applications. Celles-ci peuvent mettre en oeuvre ces verifications en parcourant le fichier /proc/pid/smaps pour des regions de la memoire ayant la pkey assignee. Plus de details sont fournis dans proc(5). Toute application voulant utiliser les cles de protection doivent etre capables de fonctionner sans elles. Elles peuvent etre indisponibles parce que le materiel executant cette application ne les prennent pas en charge, le code du noyau ne fournit aucune prise en charge ou cette prise en charge a ete desactivee, ou parce que les cles ont ete allouees, peut etre par une bibliotheque utilisee par l'application. Il est recommande aux applications voulant utiliser les cles de protection de simplement appeler pkey_alloc(2) et de tester si l'appel reussit au lieu d'essayer de detecter une prise en charge de la fonctionnalite par tout autre moyen. Quoique non necessaire, la prise en charge materielle des cles de protection peut etre determinee a l'aide de l'instruction cpuid. La maniere de realiser cela est decrite dans le manuel pour les developpeurs de logiciels pour Intel. Le noyau realise ce denombrement et expose cette information dans le champ << flags >> de /proc/cpuinfo. La chaine << pku >> dans ce champ indique la prise en charge materielle des cles de protection et la chaine << ospke >> indique que le noyau gere et active la prise en charge des cles de protection. Les applications utilisant les threads et les cles de protection doivent etre particulierement attentives. Les threads heritent des droits des cles de protection de leur parent au moment de l'appel systeme clone(2). Les applications doivent aussi s'assurer que leurs propres permissions sont appropriees pour les threads enfant au moment de l'appel clone(2) ou de s'assurer que chaque thread enfant peut realiser sa propre initialisation des droits de cles de protection. Comportement du gestionnaire de signal Chaque fois qu'un gestionnaire de signal est invoque (y compris pour les signaux imbriques), le thread obtient temporairement un nouvel ensemble par defaut de droits de cles de protection qui outrepasse les droits du contexte interrompu. Cela signifie que les applications doivent retablir les droits desires des cles de protection lors de l'utilisation d'un gestionnaire de signal si ces droits different de ceux par defaut. Les droits de n'importe quel contexte sont restaures lors du renvoi du gestionnaire de signal. Ce comportement de signal est inhabituel et est du au fait que le registre PKRU x86 (qui stocke les droits d'acces des cles de protection) est gere avec le meme mecanisme materiel (XSAVE) qui gere les registres de virgule flottante. Le comportement du signal est le meme que celui des registres de virgule flottante. Appels systeme des cles de protection Le noyau Linux met en oeuvre les appels systeme suivants relatifs aux cles de protection : pkey_mprotect(2), pkey_alloc(2) et pkey_free(2). Les appels systeme de Linux pour pkey sont disponibles uniquement si le noyau a ete configure et construit avec l'option CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS. EXEMPLES Le programme ci-dessous alloue une page de memoire avec les permissions en lecture et ecriture. Puis il ecrit quelques donnees dans la memoire et les relit avec succes. Apres cela, il essaie d'allouer une cle de protection et desactive l'acces a la page en utilisant l'instruction WRPKRU. Il essaie alors d'acceder a la page qui est supposee provoquer un signal fatal pour l'application. $ ./a.out le buffer contient : 73 sur le point de lire le buffer de nouveau... Segmentation fault (core dumped) Source du programme #define _GNU_SOURCE #include #include #include #include #include int main(void) { int status; int pkey; int *buffer; /* * Allocation d'une page de memoire. */ buffer = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (buffer == MAP_FAILED) err(EXIT_FAILURE, "mmap"); /* * Mise de donnees aleatoires dans la page (toujours OK a affecter). */ *buffer = __LINE__; printf("le buffer contient : %d\n", *buffer); /* * Allocation d'une cle de protection : */ pkey = pkey_alloc(0, 0); if (pkey == -1) err(EXIT_FAILURE, "pkey_alloc"); /* * Desactivation de l'acces a toute memoire avec l'ensemble * << pkey >>, meme si aucun droit n'existe a ce moment. */ status = pkey_set(pkey, PKEY_DISABLE_ACCESS); if (status) err(EXIT_FAILURE, "pkey_set"); /* * Mettre la cle de protection dans << buffer >>. * Noter que c'est toujours lect./ecrit. aussi longtemps que mprotect() * est concerne et que le pkey_set() precedent l'ecrase. */ status = pkey_mprotect(buffer, getpagesize(), PROT_READ | PROT_WRITE, pkey); if (status == -1) err(EXIT_FAILURE, "pkey_mprotect"); printf("sur le point de lire le buffer de nouveau...\n"); /* * Cela va planter car l'acces a ete desactive. */ printf("le buffer contient : %d\n", *buffer); status = pkey_free(pkey); if (status == -1) err(EXIT_FAILURE, "pkey_free"); exit(EXIT_SUCCESS); } VOIR AUSSI pkey_alloc(2), pkey_free(2), pkey_mprotect(2), sigaction(2) TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Paul Guillonneau Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 pkeys(7)