xref: /freebsd/tools/test/stress2/misc/sigreturn4.sh (revision 4d846d26)
1#!/bin/sh
2
3# panic: vm_fault_lookup: fault on nofault entry, addr: 0
4# cpuid = 2
5# time = 1661698922
6# KDB: stack backtrace:
7# db_trace_self_wrapper(b,2931e740,2931e742,ffc0ddb8,190431,...) at db_trace_self_wrapper+0x28/frame 0xffc0dd24
8# vpanic(150acba,ffc0dd60,ffc0dd60,ffc0de20,12cc155,...) at vpanic+0xf4/frame 0xffc0dd40
9# panic(150acba,14ec1ab,0,146253d,1430,...) at panic+0x14/frame 0xffc0dd54
10# vm_fault(1e360c8,0,4,0,0) at vm_fault+0x1725/frame 0xffc0de20
11# vm_fault_trap(1e360c8,3b,4,0,0,0) at vm_fault_trap+0x52/frame 0xffc0de48
12# trap_pfault(3b,0,0) at trap_pfault+0x176/frame 0xffc0de94
13# trap(ffc0df6c,8,28,28,19156000,...) at trap+0x2d9/frame 0xffc0df60
14# calltrap() at 0xffc031ef/frame 0xffc0df60
15# --- trap 0xc, eip = 0x3b, esp = 0xffc0dfac, ebp = 0xffc0340c ---
16# (null)() at 0x3b/frame 0xffc0340c
17# KDB: enter: panic
18# [ thread pid 54680 tid 102765 ]
19# Stopped at      kdb_enter+0x34: movl    $0,kdb_why
20# db> x/s version
21# version:        FreeBSD 14.0-CURRENT #0 main-n257606-9ea2716b775-dirty: Thu Aug 25 10:47:45 CEST 2022
22# pho@mercat1.netperf.freebsd.org:/media/ob
23# j/usr/src/i386.i386/sys/PHO\012
24# db> show proc
25# Process 54680 (date) at 0x28905d50:
26#  state: NORMAL
27#  uid: 0  gids: 0, 0, 5
28#  parent: pid 785 at 0x26c14000
29#  ABI: FreeBSD ELF32
30#  flag: 0x10004002  flag2: 0
31#  arguments: date +%s
32#  reaper: 0x18c710a4 reapsubtree: 1
33#  sigparent: 20
34#  vmspace: 0x29332100
35#    (map 0x29332100)
36#    (map.pmap 0x29332174)
37#    (pmap 0x293321b0)
38#  threads: 1
39# 102765                   Run     CPU 2               date
40# db>
41
42[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
43prog=sigreturn4
44
45cat > /tmp/$prog.c <<EOF
46#include <sys/types.h>
47#include <sys/resource.h>
48#include <sys/stat.h>
49#include <sys/syscall.h>
50#include <sys/wait.h>
51
52#include <ucontext.h>
53#include <err.h>
54#include <errno.h>
55#include <fcntl.h>
56#include <libutil.h>
57#include <pthread.h>
58#include <pwd.h>
59#include <signal.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63#include <unistd.h>
64
65#define RUNTIME 120
66#define THREADS 1
67
68static void
69hand(int i __unused) {	/* handler */
70	_exit(1);
71}
72
73static long
74random_long(long mi, long ma)
75{
76        return (arc4random()  % (ma - mi + 1) + mi);
77}
78
79static void
80flip(void *ap, size_t len)
81{
82	unsigned char *cp;
83	int byte;
84	unsigned char bit, buf, mask, old __unused;
85
86	cp = (unsigned char *)ap;
87	byte = random_long(0, len);
88	bit = random_long(0,7);
89	mask = ~(1 << bit);
90	buf = cp[byte];
91	old = cp[byte];
92	buf = (buf & mask) | (~buf & ~mask);
93	cp[byte] = buf;
94}
95
96static void *
97churn(void *arg __unused)
98{
99	time_t start;
100
101	start = time(NULL);
102	while (time(NULL) - start < 10) {
103		usleep(100);
104	}
105	return(NULL);
106}
107
108static void *
109calls(void *arg __unused)
110{
111	time_t start;
112	ucontext_t uc;
113	int i, n;
114
115	start = time(NULL);
116	for (i = 0; time(NULL) - start < 10; i++) {
117		n = 0;
118		if (getcontext(&uc) == -1)
119			err(1, "getcontext");
120		n++;
121
122		if (n == 1) {
123			flip(&uc, sizeof(uc));
124			alarm(1);
125			if (sigreturn(&uc) == -1)
126				err(1, "sigreturn()");
127		} else
128			break;
129	}
130	return (NULL);
131}
132
133int
134main(int argc, char **argv)
135{
136	struct passwd *pw;
137	struct rlimit limit;
138	pid_t pid;
139	pthread_t rp, cp[THREADS];
140	time_t start;
141	int e, j;
142
143	if ((pw = getpwnam("nobody")) == NULL)
144		err(1, "failed to resolve nobody");
145
146	if (getenv("USE_ROOT") && argc == 2)
147		fprintf(stderr, "Running sigreturn4 as root for %s.\n",
148				argv[1]);
149	else {
150		if (setgroups(1, &pw->pw_gid) ||
151		    setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
152		    seteuid(pw->pw_uid) || setuid(pw->pw_uid))
153			err(1, "Can't drop privileges to \"nobody\"");
154		endpwent();
155	}
156
157	limit.rlim_cur = limit.rlim_max = 1000;
158#if defined(RLIMIT_NPTS)
159	if (setrlimit(RLIMIT_NPTS, &limit) < 0)
160		err(1, "setrlimit");
161#endif
162
163	signal(SIGALRM, hand);
164	signal(SIGILL,  hand);
165	signal(SIGFPE,  hand);
166	signal(SIGSEGV, hand);
167	signal(SIGBUS,  hand);
168	signal(SIGURG,  hand);
169	signal(SIGSYS,  hand);
170	signal(SIGTRAP, hand);
171
172	if (daemon(1, 1) == -1)
173		err(1, "daemon()");
174
175	start = time(NULL);
176	while ((time(NULL) - start) < RUNTIME) {
177		if ((pid = fork()) == 0) {
178			if ((e = pthread_create(&rp, NULL, churn, NULL)) != 0)
179			errc(1, e, "pthread_create");
180			for (j = 0; j < THREADS; j++)
181				if ((e = pthread_create(&cp[j], NULL, calls,
182				    NULL)) != 0)
183					errc(1, e, "pthread_create");
184			for (j = 0; j < THREADS; j++)
185				pthread_join(cp[j], NULL);
186
187			if ((e = pthread_kill(rp, SIGINT)) != 0)
188				errc(1, e, "pthread_kill");
189			if ((e = pthread_join(rp, NULL)) != 0)
190				errc(1, e, "pthread_join");
191			_exit(0);
192		}
193		waitpid(pid, NULL, 0);
194	}
195
196	return (0);
197}
198EOF
199
200cd /tmp
201cc -o $prog -Wall -Wextra -O0 $prog.c -lpthread || exit 1
202start=`date +%s`
203while [ $((`date +%s` - start)) -lt 300 ]; do
204	./$prog > /dev/null 2>&1
205	date +%T
206done
207rm -f /tmp/$prog /tmp/$ptog.c /tmp/$prog.core
208exit 0
209