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

linux, page-fault

Solution

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
    }
    ...
}

Problem

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.

Original source