Notez que je n'ai pas vraiment compris le mprotect régulier à la suite de strace
mprotect (2) est un appel système qui contrôle les autorisations de zone mémoire.
#include <sys/mman.h>
int mprotect(const void *addr, size_t len, int prot);
Passez le pointeur, la taille et la somme logique des bits.
Actuellement, les bits de protection qui peuvent être combinés en prenant le OU
Nom du drapeau | Aperçu |
---|---|
PROT_NONE | Aucune protection du tout |
PROT_READ | La page est lisible |
PROT_WRITE | La page est accessible en écriture |
PROT_EXEC | La page est exécutable |
En cas de succès, mprotect () renvoie 0. En cas d'erreur, -1 est renvoyé et errno est défini de manière appropriée.
errno | Aperçu |
---|---|
EACCES | Impossible de définir l'accès spécifié à la mémoire |
EINVAL | addr n'est pas un pointeur valide ou un multiple de la taille de la page système |
ENOMEM | Impossible d'allouer la structure à l'intérieur du noyau |
ENOMEM | [addr, addr+len-1]L'adresse de la plage n'est pas valide car l'espace d'adressage du processus, ou l'adresse de la plage pointe vers une ou plusieurs pages qui ne sont pas mappées. |
Un exemple de programme qui génère SIGSEGV en écrivant dans la mémoire dans la zone READ_ONLY.
SIGSEGV exécute lui-même le traitement géré à l'aide de sigaction.
mprotect.c
#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("Got SIGSEGV at address: 0x%lx\n",
(long) si->si_addr);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
char *p;
int pagesize;
//Modifications du comportement du signal
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 de la mémoire alignée
buffer = memalign(pagesize, 4 * pagesize);
if (buffer == NULL)
handle_error("memalign");
printf("Start of region: 0x%lx\n", (long) buffer);
//Contrôler les autorisations de la zone de mémoire
if (mprotect(buffer + pagesize * 2, pagesize, PROT_READ) == -1)
handle_error("mprotect");
for (p = buffer ; ; )
*(p++) = 'a';
printf("Loop completed\n"); /* Should never happen */
exit(EXIT_SUCCESS);
}
Recommended Posts