Subject: kern/14855: sparc sigreturn sometimes trashes user stack
To: None <gnats-bugs@gnats.netbsd.org>
From: Wolfgang Rupprecht <wolfgang@wsrcc.com>
List: netbsd-bugs
Date: 12/06/2001 12:02:35
>Number:         14855
>Category:       kern
>Synopsis:       sparc sigreturn sometimes trashes user stack
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 06 12:03:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Wolfgang Rupprecht
>Release:        NetBSD 1.5Y
>Organization:
W S Rupprecht Computer Consulting, Fremont CA
>Environment:
NetBSD poblano.wsrcc.com 1.5Y NetBSD 1.5Y (GENERIC) #0: Mon Nov 12 00:14:47 UTC 2001     root@sparc20:/usr/obj/amd/celeron/root/local1/src/src/sys/arch/sparc/co
Architecture: i386
Machine: i386

>Description:

    The user's stack gets trashed a small percentage of the time by
    sigreturn(); In this test program a "can't happen" default branch
    does indeed happen with disturbing frequency.
	
    Observed on the following sparc type and kernel:

	NetBSD 1.5Y (GENERIC) #0: Mon Nov 12 00:14:47 UTC 2001
	    root@sparc20:/usr/obj/amd/celeron/root/local1/src/src/sys/arch/sparc/compile
	/GENERIC
	total memory = 65144 KB
	avail memory = 57176 KB
	using 839 buffers containing 3356 KB of memory
	bootpath: /iommu@0,10000000/sbus@0,10001000/espdma@5,8400000/esp@5,8800000/sd@1,
	0
	mainbus0 (root): SUNW,SPARCstation-5
	cpu0 at mainbus0: MB86904 @ 85 MHz, on-chip FPU
	cpu0: 16K instruction (32 b/l), 8K data (16 b/l): cache enabled
    
>How-To-Repeat:

    Compile and run the following.  This is what it prints when it fails:

    $ ./sr 
    unexpected character 0x6c `l' in iclp: 8/0x6c
    $ ./sr 
    unexpected character 0x63 `c' in iclp: 20/0x63
    unexpected character 0x69 `i' in iclp: 21/0x69
    unexpected character 0x6c `l' in iclp: 29/0x6c
    unexpected character 0x69 `i' in iclp: 33/0x69
    unexpected character 0x63 `c' in iclp: 39/0x63
    unexpected character 0x69 `i' in iclp: 43/0x69
    unexpected character 0x70 `p' in iclp: 47/0x70
    unexpected character 0x69 `i' in iclp: 55/0x69
    unexpected character 0x69 `i' in iclp: 60/0x69
    $ ./sr 
    unexpected character 0x6c `l' in iclp: 3/0x6c
    unexpected character 0x6c `l' in iclp: 8/0x6c
    unexpected character 0x6c `l' in iclp: 25/0x6c
    

/* source 'sr.c' follows.  Compile with "cc -O2 -ggdb -o sr sr.c" */

#include <sys/time.h>

#include <signal.h>
#include <stdio.h>

volatile int o0;
volatile int count;


void
sig_handler(int sig, int blah, void *x)
{
	struct sigcontext * scp = x;

	count++;
#ifdef __sparc__
	o0 = scp->sc_o0;
#endif
	sigreturn(scp);
}

void
test2(char *fmt)
{
	char *ofmt = fmt;

	for (; *fmt; fmt++)
	  switch (*fmt) {
	  case 'i':
	  case 'c':
	  case 'l':
	  case 'p':
	    break;
	  default:
	    fprintf(stderr,
		    "unexpected character 0x%02x `%c' in %s: %d/0x%02x\n",
		    *fmt, *fmt, ofmt, count, o0);
	  }
}

int
main(int argc, char * argv[])
{
	struct sigaction act;
	struct itimerval itimer;

	sigfillset(&act.sa_mask);
	act.sa_handler = sig_handler;
	act.sa_flags = SA_RESTART;

	sigaction(SIGVTALRM, &act, NULL);

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = 10000;
	
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = 10000;
	
	setitimer(ITIMER_VIRTUAL, &itimer, NULL);

	while (1)
		test2("iclp");
}
	
>Fix:
	
>Release-Note:
>Audit-Trail:
>Unformatted:
 	sparc 2001-11-12 snapshot on ftp.netbsd.org