Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify read or write operations of page fault when using sigaction handler on SIGSEGV?(LINUX)

I use sigaction to handle page fault exception, and the handler function is defind like this:

void sigaction_handler(int signum, siginfo_t *info, void *_context)

So it's easy to get page fault address by reading info->si_addr.

The question is, how to know whether this operation is memory READ or WRITE ?

I found the type of _context parameter is ucontext_t defined in /usr/include/sys/ucontext.h

There is a cr2 field defined in mcontext_t, but unforunately, it is only avaliable when x86_64 is not defind, thus I could not used cr2 to identify read/write operations.

On anotherway, there is a struct named sigcontext defined in /usr/include/bits/sigcontext.h This struct contains cr2 field. But I don't know where to get it.

like image 834
user2586415 Avatar asked Jul 16 '13 08:07

user2586415


People also ask

Does sigaction call the signal handler?

sigaction() can be called with a NULL second argument to query the current signal handler. It can also be used to check whether a given signal is valid for the current machine by calling it with NULL second and third arguments.

What does sigaction do in C?

The sigaction() function allows the calling process to examine and/or specify the action to be associated with a specific signal. The argument sig specifies the signal; acceptable values are defined in <signal. h>. Pointer to a signal-catching function or one of the macros SIG_IGN or SIG_DFL.

What is the difference between signal and sigaction?

The signal() function does not (necessarily) block other signals from arriving while the current handler is executing; sigaction() can block other signals until the current handler returns.

Should I use signal or sigaction?

Therefore, if you use signal to save and later reestablish an action, it may not be able to reestablish properly a handler that was established with sigaction . To avoid having problems as a result, always use sigaction to save and restore a handler if your program uses sigaction at all.


1 Answers

You can check this in x86_64 by referring to the ucontext's mcontext struct and the err register:

void pf_sighandler(int sig, siginfo_t *info, ucontext_t *ctx) {
    ...
    if (ctx->uc_mcontext.gregs[REG_ERR] & 0x2) {
        // Write fault
    } else {
        // Read fault
    }
    ...
}
like image 97
webbhorn Avatar answered Sep 23 '22 14:09

webbhorn