Bug 20065

Summary: sigcontext mismatch?
Product: [Retired] Red Hat Linux Reporter: Len Widra <lenwidra>
Component: kernelAssignee: Arjan van de Ven <arjanv>
Status: CLOSED CURRENTRELEASE QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 9   
Target Milestone: ---   
Target Release: ---   
Hardware: i686   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2004-09-30 15:38:51 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Len Widra 2000-10-30 21:17:53 UTC
For x86 platforms, it seems like there's a mismatch between
1) the sigcontext structure defined in RH 7.0 /usr/include/asm/sigcontext.h
and
2) the structure that is actually pushed as the third argument to a signal
handler.

As a result, the "offending PC" ends up in the "fpstate" member rather
than in "cr2", where it's presumably supposed to be.

I haven't found a man page description for the third arg passed to a signal
handler, so it's hard to be certain what's intended.  "man sigaction" just
shows this arg as a "void *" with no further explanation.

Below is illustrative test code.


#include <sys/ucontext.h>

#define SIGCONTEXTPC fpstate /* Actually, the PC! */

void
fatal_signal_error_handler(int signo, siginfo_t *sinfo, void *pcontext)
{
	char PCbuf[32];
	struct sigcontext *context = pcontext;

	printf("pid %d sees signal %d\n", getpid(), signo);
	printf("si_code is 0x%x\n", sinfo->si_code);
	printf("si_addr is 0x%x\n", (long)(sinfo->si_addr));
	sprintf(PCbuf, "0x%x", context->SIGCONTEXTPC);
	printf("offending PC is %s\n", PCbuf);
	sleep(100000); /* Allow gdb to be used on running process */
}


void set_signals()
{
	int sig;
	struct sigaction sigact;

	sigact.sa_sigaction = fatal_signal_error_handler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = SA_SIGINFO;
	sigact.sa_restorer = 0;

	sigaction(SIGSEGV, &sigact, 0);
}

main()
{
	char *badaddr = (char *)0x37;
	int x;

	set_signals();

	x = *badaddr;
}

Comment 1 Alan Cox 2003-06-05 22:19:22 UTC
Example still works on RH9. Needs review to verify if it is in fact correct or not


Comment 2 Bugzilla owner 2004-09-30 15:38:51 UTC
Thanks for the bug report. However, Red Hat no longer maintains this version of
the product. Please upgrade to the latest version and open a new bug if the problem
persists.

The Fedora Legacy project (http://fedoralegacy.org/) maintains some older releases, 
and if you believe this bug is interesting to them, please report the problem in
the bug tracker at: http://bugzilla.fedora.us/