Zaid Alali
Zaid Alali

Reputation: 69

How to make mprotect() to make forward progress after handling pagefaulte exception?

I wan to intercept all memory references to a specific memory block in my application using mprotect(), so I slightly modified the mprotect sample code found here. When I ran the modified code, however, the application would not make a forward progress past the first exception caught. Instead, Linux will keep on sending the exception to my application, and my application will keep printing out the same line in an infinite loop.

Now, my problem is how to tell Linux to move forward and progress to the next instruction.

Here is a sample of the output:

Got SIGSEGV at address: 0x1556000
value of i is: 8192
Got SIGSEGV at address: 0x1556000
value of i is: 8192
/* Infinitely repeats the above two messages. */

And here is the code:

#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;
int i;

static void handler(int sig, siginfo_t *si, void *unused)
{
    printf("Got SIGSEGV at address: 0x%lx\nvalue of i is: %d\n",
            (long) si->si_addr, i);
   //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");

    /* Allocate a buffer aligned on a page boundary;
    initial protection is 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_READ) == -1)
        handle_error("mprotect");


    //for (p = buffer, i = 0 ; i < 10 ; ++i )
    //  *(p++) = 'a';

    for (p = buffer ; i< 8200; ++i )
        *(p++) = 'a';

    printf("Loop completed\n");     /* Should never happen */
    exit(EXIT_SUCCESS);
}

Upvotes: 2

Views: 123

Answers (0)

Related Questions