mprotect   Début   Suivant   Sommaire   Préc.page.lue   Accueil
Section: Manuel du programmeur Linux (2)
Updated: 6 juin 2008
Sommaire  



NOM   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
mprotect - Modifier la protection d'une partie de la mémoire  



SYNOPSIS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
#include <sys/mman.h>

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



DESCRIPTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
mprotect() modifie la protection de la (des) page(s) du processus appelant contenant tout ou une partie de l'intervalle [addraddr+len-1]. addr doit être alignée sur une frontière de page.

Si le processus appelant essaye d'accéder à la mémoire d'une manière telle que cela viole la protection, le noyau génère un signal SIGSEGV pour ce processus.

prot est 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
On peut exécuter la zone de mémoire.
 



VALEUR RENVOYÉE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
mprotect() renvoie 0 s'il réussit, ou -1 s'il échoue, auquel cas errno contient le code d'erreur.  



ERREURS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
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.
EFAULT
La mémoire n'est pas accessible.
EINVAL
addr n'est pas un pointeur valide, ou ce n'est pas un multiple de la taille de page système.
ENOMEM
Pas assez de mémoire pour le noyau. Ou : les adresses de l'intervalle [addr, addr+len] ne sont pas valides pour l'espace d'adresse du processus, ou spécifient une ou plusieurs pages qui ne sont pas projetées.
 



CONFORMITÉ   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
SVr4, POSIX.1-2001. POSIX précise que le comportement de mprotect() n'est pas spécifié s'il est appliqué à une zone de mémoire qui n'a pas été obtenue avec mmap(2).  



NOTES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Sous Linux, il est toujours permis d'appeler mprotect() sur une adresse d'un espace d'adresse processus (excepté pour la zone vsyscall du noyau). En particulier, il peut être utiliser pour modifier une zone de code 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'un implémentation peut permettre un accès autre que celui défini dans prot, mais doit au minimum autoriser l'accès si PROT_WRITE est positionné et ne doit pas l'autoriser si PROT_NONE est positionné.  




EXEMPLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le programme suivant alloue quatre pages de mémoire en faisant de la troisième une page en lecture seule, et exécute une boucle qui vient marcher sur la zone mémoire allouée, modifiant les octets.

$ ./a.out
Start of region:        0x804c000
Got SIGSEGV at address: 0x804e000

#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)

char *buffer;

static void
handler(int sig, siginfo_t *si, void *unused)
{
    printf("Got SIGSEGV at address: 0x%lx\n", 
            (long) si->si_addr);
    exit(EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
    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");
   }

    /* Alloue un tampon aligné sur une frontière de page ;
       la protection initiale est PROT_READ | PROT_WRITE */

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

    printf("Start of region:        0x%lx\n", (long) buffer);

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

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

    printf("Loop completed\n");     /* Ne devrait jamais arriver */
    exit(EXIT_SUCCESS);
}
 



VOIR AUSSI   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
mmap(2), sysconf(3)  



TRADUCTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 12 octobre 1996 et révisée le 6 juin 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 mprotect ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.


 



Sommaire   Début   Suivant   Sommaire   Préc.page.lue   Accueil
NOM
SYNOPSIS
DESCRIPTION
VALEUR RENVOYÉE
ERREURS
CONFORMITÉ
NOTES
EXEMPLE
VOIR AUSSI
TRADUCTION

Table des mots clés   Début   Suivant   Sommaire   Préc.page.lue   Accueil
EACCESERREURS
EFAULTERREURS
EINVALERREURS
ENOMEMERREURS
PROT_EXECDESCRIPTION
PROT_NONEDESCRIPTION
PROT_READDESCRIPTION
PROT_WRITEDESCRIPTION



Ce document a été créé par man2html suivi de man2html.pl, le 17/10/2008 17:49:16, en utilisant les pages de 'man'.
 

Valid HTML 4.01 Transitional