Provided by: manpages-fr-dev_3.65d1p1-1_all bug

NOM

       mprotect - Changer la protection d'une partie de la mémoire

SYNOPSIS

       #include <sys/mman.h>

       int mprotect(void *addr, size_t len, int prot);

DESCRIPTION

       mprotect()  change  la  protection  pour  la  (les)  page(s) mémoire du processus appelant
       contenant tout ou une partie de l'intervalle [addr, addr+len-1]. addr doit être aligné sur
       une page.

       Si  le processus appelant essaie d'accéder à la mémoire en violant la protection, le noyau
       génère un signal SIGSEGV pour ce processus.

       prot soit PROT_NONE, soit un OU binaire « | » entre les valeurs suivantes :

       PROT_NONE  On ne peut pas accéder du tout à la zone de mémoire.

       PROT_READ  On peut lire la zone de mémoire.

       PROT_WRITE On peut modifier la zone de mémoire.

       PROT_EXEC  La zone de mémoire peut contenir du code exécutable.

VALEUR RENVOYÉE

       mprotect() renvoie 0 s'il réussit, ou -1 s'il échoue, auquel cas errno  contient  le  code
       d'erreur.

ERREURS

       EACCES L'accès  spécifié  n'est  pas  possible sur ce type de mémoire. Ceci se produit par
              exemple si vous utilisez mmap(2) pour représenter un fichier en  lecture  seule  en
              mémoire, et si vous demandez de marquer cette zone avec PROT_WRITE.

       EINVAL addr n'est pas un pointeur valide, ou ce n'est pas un multiple de la taille de page
              du système.

       ENOMEM Impossible d'allouer des structures internes au noyau.

       ENOMEM Les adresses dans  l'intervalle  [addr,  addr+len-1]  ne  sont  pas  valables  dans
              l'espace  d'adressage  du  processus,  ou  l'intervalle  s'étend  sur des pages non
              projetées (dans les noyaux antérieurs à 2.4.19, l'erreur EFAULT  était  produite  à
              tort dans ce cas).

CONFORMITÉ

       SVr4,  POSIX.1-2001.  POSIX  précise  que le comportement de mprotect() n'est pas spécifié
       s'il est appliqué sur des zones de mémoire non obtenues avec mmap(2).

NOTES

       Sous Linux, il est toujours autorisé d'appeler mprotect()  sur  une  adresse  de  l'espace
       d'adressage du processus (excepté pour la zone vsyscall du noyau). En particulier, il peut
       être utilisé pour rendre une projection de code existante accessible en écriture.

       La différence entre PROT_EXEC et PROT_READ dépend de l'architecture et de  la  version  du
       noyau.  Sur  certaines  architectures matérielles (par exemple, i386), PROT_WRITE implique
       PROT_READ.

       POSIX.1-2001 indique qu'une implémentation peut autoriser un accès autre que  celui  donné
       dans  prot,  mais doit au minimum autoriser l'accès en écriture si PROT_WRITE était passé,
       et ne doit autoriser aucun accès si PROT_NONE était passé.

EXEMPLE

       Le programme ci‐dessous alloue quatre pages de mémoire, rend la  troisième  accessible  en
       lecture  seule,  puis exécute une boucle qui se déplace en avançant dans la région allouée
       et en modifiant son contenu.

       Voici un exemple d'exécution de ce programme :

           $ ./a.out
           Début de la région :       0x804c000
           Reçu SIGSEGV à l'adresse : 0x804e000

   Source du programme

       #include <unistd.h>
       #include <signal.h>
       #include <stdio.h>
       #include <malloc.h>
       #include <stdlib.h>
       #include <errno.h>
       #include <sys/mman.h>

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       static char *buffer;

       static void
       handler(int sig, siginfo_t *si, void *unused)
       {
           printf("Reçu SIGSEGV à l'adresse : 0x%lx\n",
                   (long) si->si_addr);
           exit(EXIT_FAILURE);
       }

       int
       main(int argc, char *argv[])
       {
           char *p;
           int pagesize;
           struct sigaction sa;

           sa.sa_flags = SA_SIGINFO;
           sigemptyset(&sa.sa_mask);
           sa.sa_sigaction = handler;
           if (sigaction(SIGSEGV, &sa, NULL) == -1)
               handle_error("sigaction");

           pagesize = sysconf(_SC_PAGE_SIZE);
           if (pagesize == -1)
               handle_error("sysconf");

           /* Allouer un tampon aligné sur une page ;
              la protection initiale est PROT_READ | PROT_WRITE */

           buffer = memalign(pagesize, 4 * pagesize);
           if (buffer == NULL)
               handle_error("memalign");

           printf("Début de la région :       0x%lx\n", (long) buffer);

           if (mprotect(buffer + pagesize * 2, pagesize,
                       PROT_READ) == -1)
               handle_error("mprotect");

           for (p = buffer ; ; )
               *(p++) = 'a';

           printf("Boucle terminée\n");     /* Ne devrait jamais arriver */
           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       mmap(2), sysconf(3)

COLOPHON

       Cette page fait partie de la publication 3.65 du projet man-pages Linux.  Une  description
       du  projet  et  des  instructions  pour  signaler  des  anomalies  peuvent être trouvées à
       l'adresse http://www.kernel.org/doc/man-pages/.

TRADUCTION

       Depuis   2010,   cette   traduction   est   maintenue   à   l'aide   de    l'outil    po4a
       <http://po4a.alioth.debian.org/>  par l'équipe de traduction francophone au sein du projet
       perkamon <http://perkamon.alioth.debian.org/>.

       Christophe   Blaess   <http://www.blaess.fr/christophe/>   (1996-2003),    Alain    Portal
       <http://manpagesfr.free.fr/>  (2003-2006).  Julien  Cristau  et  l'équipe  francophone  de
       traduction de Debian (2006-2009).

       Veuillez     signaler     toute     erreur     de     traduction     en     écrivant     à
       <debian-l10n-french@lists.debian.org>   ou   par   un  rapport  de  bogue  sur  le  paquet
       manpages-fr.

       Vous pouvez toujours avoir accès à la version anglaise de  ce  document  en  utilisant  la
       commande « man -L C <section> <page_de_man> ».