Reputation: 3053
I have created a signal handler to get called when SIGSEGV is sent. I am using C to write my programs and also using Linux and intel x86 processor. In the sig handler it looks like the si_addr that is passed in through the siginfo_t struct is given the value 0 instead of the value of the address of the instruction causing the problem. I set the SIG_INFO flag in sigaction so idk why this is happening.
Here is some example code:
int main(){
mprotect(..., PROC_READ | PROC_WRITE /* | PROC_EXEC */); //cannot execute page
someMethodOnRestrictedPage();
//do some stuff
}
void init_sighandler(void) {
//initialize the sigaction so that sig handler is called when a SIGSEGV is thrown
struct sigaction * action;
action = (struct sigaction *) malloc(sizeof(struct sigaction));
action->sa_sigaction = sighandler;
sigemptyset (&action->sa_mask);
action->sa_flags = 0;
sigaddset(&action->sa_mask, SA_SIGINFO);
sigaddset(&action->sa_mask, SA_RESTART);
sigaction(SIGSEGV, action, NULL);
}
void sighandler(int sig, siginfo_t *siginfo, void *ucp){
printf("%x\n", siginfo->si_addr); // prints out 0
}
Upvotes: 0
Views: 2090
Reputation: 3322
Your .sa_flags
has the SA_SIGINFO
bit cleared.
Quoting http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigaction.html,
SA_SIGINFO
If cleared and the signal is caught, the signal-catching function will be entered as:
void func(int signo);
where signo
is the only argument to the signal catching function. In this case the sa_handler
member must be used to describe the signal catching function and the application must not modify the sa_sigaction
member.
If SA_SIGINFO
is set and the signal is caught, the signal-catching function will be entered as:
void func(int signo, siginfo_t *info, void *context);
where two additional arguments are passed to the signal catching function. The second argument will point to an object of type siginfo_t
explaining the reason why the signal was generated; the third argument can be cast to a pointer to an object of type ucontext_t
to refer to the receiving process' context that was interrupted when the signal was delivered. In this case the sa_sigaction
member must be used to describe the signal catching function and the application must not modify the sa_handler
member.
The si_signo
member contains the system-generated signal number.
The si_errno
member may contain implementation-dependent additional error information; if non-zero, it contains an error number identifying the condition that caused the signal to be generated.
The si_code
member contains a code identifying the cause of the signal. If the value of si_code
is less than or equal to 0, then the signal was generated by a process and si_pid
and si_uid
respectively indicate the process ID and the real user ID of the sender. The <signal.h>
header description contains information about the signal specific contents of the elements of the siginfo_t
type.
--End quote
So sigaction uses .sa_handler
if the bit is clear, and .sa_sigaction
if the bit is set.
So you have undefined behaviour, since you're reading unwritten arguments.
Set .sa_flags = SA_SIGINFO | ...
to rectify the issue.
Upvotes: 1