Note that I didn't really understand the regular mprotect as a result of strace
mprotect (2) is a system call that controls memory area permissions.
#include <sys/mman.h>
int mprotect(const void *addr, size_t len, int prot);
Pass the pointer, size, and bitwise OR.
Currently, protection bits that can be combined with the following ORs
Flag name | Overview |
---|---|
PROT_NONE | No protection at all |
PROT_READ | Page is readable |
PROT_WRITE | Page is writable |
PROT_EXEC | Page is executable |
If successful, mprotect () returns 0. In case of an error, -1 is returned and errno is set appropriately.
errno | Overview |
---|---|
EACCES | Unable to set specified access to memory |
EINVAL | addr is not a valid pointer or is not a multiple of the system page size |
ENOMEM | Could not allocate structure inside kernel |
ENOMEM | [addr, addr+len-1]The address in the range is invalid as the process's address space, or the address in the range points to one or more pages that are not mapped. |
A sample program that generates SIGSEGV by writing to the memory in the READ_ONLY area.
SIGSEGV itself executes the processing handled using 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;
//Changes in signal behavior
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");
//Allocate aligned memory
buffer = memalign(pagesize, 4 * pagesize);
if (buffer == NULL)
handle_error("memalign");
printf("Start of region: 0x%lx\n", (long) buffer);
//Control memory area permissions
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