xref: /freebsd/tools/test/stress2/misc/kevent7.sh (revision c1d255d3)
1#!/bin/sh
2
3#
4# Copyright (c) 2013 EMC Corp.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# Threaded syscall(2) fuzz test inspired by the iknowthis test suite
30# by Tavis Ormandy <taviso  cmpxchg8b com>
31
32# kevent(2) with random arguments.
33# Spinning threads seen.
34# Fixed in r255877.
35
36# "panic: softclock_call_cc: act 0xfffff801219a0840 0" seen:
37# https://people.freebsd.org/~pho/stress/log/kevent7.txt
38# Fixed by r315289
39
40[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
41
42. ../default.cfg
43
44ulimit -t 200
45odir=`pwd`
46cd /tmp
47sed '1,/^EOF/d' < $odir/$0 > kevent7.c
48rm -f /tmp/kevent7
49mycc -o kevent7 -Wall -Wextra -O2 -g kevent7.c -lpthread || exit 1
50rm -f kevent7.c
51
52mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
53mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
54
55mdconfig -a -t swap -s 2g -u $mdstart || exit 1
56bsdlabel -w md$mdstart auto
57newfs $newfs_flags md${mdstart}$part > /dev/null
58mount /dev/md${mdstart}$part $mntpoint
59chmod 777 $mntpoint
60
61for i in `jot 5`; do
62	(cd $mntpoint; /tmp/kevent7 $* < /dev/null) &
63	sleep 60
64	while pgrep -q kevent7; do
65		pkill -9 kevent7
66		sleep 1
67	done
68done
69
70for i in `jot 5`; do
71	mount | grep -q md${mdstart}$part  && \
72		umount $mntpoint && mdconfig -d -u $mdstart && break
73	sleep 10
74done
75if mount | grep -q md${mdstart}$part; then
76	fstat $mntpoint
77	echo "umount $mntpoint failed"
78	exit 1
79fi
80rm -f /tmp/kevent7
81exit 0
82EOF
83#include <sys/types.h>
84#include <sys/event.h>
85#include <sys/param.h>
86#include <sys/stat.h>
87#include <sys/syscall.h>
88#include <sys/wait.h>
89
90#include <err.h>
91#include <errno.h>
92#include <fcntl.h>
93#include <fts.h>
94#include <libutil.h>
95#include <pthread.h>
96#include <pwd.h>
97#include <signal.h>
98#include <sys/socket.h>
99#include <stdint.h>
100#include <stdio.h>
101#include <stdlib.h>
102#include <string.h>
103#include <unistd.h>
104
105#define THREADS 50
106
107int fd[900], fds[2], socketpr[2];
108#define N (128 * 1024 / (int)sizeof(u_int32_t))
109static u_int32_t r[N];
110static int syscallno;
111
112static void
113hand(int i __unused) {	/* handler */
114	_exit(1);
115}
116
117static unsigned long
118makearg(void)
119{
120	unsigned int i;
121	unsigned long val;
122
123	val = arc4random();
124	i   = arc4random() % 100;
125	if (i < 20)
126		val = val & 0xff;
127	if (i >= 20 && i < 40)
128		val = val & 0xffff;
129	if (i >= 40 && i < 60)
130		val = (unsigned long)(r) | (val & 0xffff);
131#if defined(__LP64__)
132	if (i >= 60) {
133		val = (val << 32) | arc4random();
134		if (i > 80)
135			val = val & 0x00007fffffffffffUL;
136	}
137#endif
138
139	return(val);
140}
141
142static void *
143test(void *arg __unused)
144{
145
146	FTS		*fts;
147	FTSENT		*p;
148	int		ftsoptions;
149	int i;
150	char		*args[5];
151
152	ftsoptions = FTS_PHYSICAL;
153	args[0] = "/dev";
154	args[1] = "/proc";
155	args[2] = "/usr/compat/linux/proc";
156	args[3] = ".";
157	args[4] = 0;
158
159	for (;;) {
160		for (i = 0; i < N; i++)
161			r[i] = arc4random();
162		if ((fts = fts_open(args, ftsoptions, NULL)) == NULL)
163			err(1, "fts_open");
164
165		i = 0;
166		while ((p = fts_read(fts)) != NULL) {
167			if (fd[i] > 0)
168				close(fd[i]);
169			if ((fd[i] = open(p->fts_path, O_RDWR)) == -1)
170				if ((fd[i] = open(p->fts_path, O_WRONLY)) ==
171				    -1)
172					if ((fd[i] = open(p->fts_path,
173					    O_RDONLY)) == -1)
174						continue;
175			i++;
176			i = i % nitems(fd);
177		}
178
179		if (fts_close(fts) == -1)
180			if (errno != ENOTDIR)
181				warn("fts_close()");
182		if (pipe(fds) == -1)
183			err(1, "pipe()");
184		if (socketpair(PF_UNIX, SOCK_SEQPACKET, 0, socketpr) == -1)
185			err(1, "socketpair()");
186		sleep(1);
187		close(socketpr[0]);
188		close(socketpr[1]);
189		close(fds[0]);
190		close(fds[1]);
191	}
192	return(0);
193}
194
195static void *
196calls(void *arg __unused)
197{
198	unsigned long arg1, arg2, arg3, arg4, arg5, arg6, arg7;
199	int i, kq, num;
200
201	if ((kq = kqueue()) < 0)
202		err(1, "kqueue()");
203	for (i = 0; i < 1000; i++) {
204		if (i == 0)
205			usleep(1000);
206		num = syscallno;
207		arg1 = makearg();
208		arg2 = makearg();
209		arg3 = makearg();
210		arg4 = makearg();
211		arg5 = makearg();
212		arg6 = makearg();
213		arg7 = makearg();
214
215#if 0
216		fprintf(stderr, "%2d : syscall(%3d, %lx, %lx, %lx, %lx, %lx,"
217		   " %lx, %lx)\n",
218			i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
219#endif
220		alarm(1);
221		syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
222		num = 0;
223	}
224	close(kq);
225
226	return (0);
227}
228
229int
230main(void)
231{
232	struct passwd *pw;
233	time_t start;
234	pthread_t rp, cp[THREADS];
235	int e, j, n;
236
237	if ((pw = getpwnam("nobody")) == NULL)
238		err(1, "no such user: nobody");
239
240	if (setgroups(1, &pw->pw_gid) ||
241	    setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
242	    seteuid(pw->pw_uid) || setuid(pw->pw_uid))
243		err(1, "Can't drop privileges to \"nobody\"");
244	endpwent();
245
246	signal(SIGALRM, hand);
247	signal(SIGILL,  hand);
248	signal(SIGFPE,  hand);
249	signal(SIGSEGV, hand);
250	signal(SIGBUS,  hand);
251	signal(SIGURG,  hand);
252	signal(SIGSYS,  hand);
253	signal(SIGTRAP, hand);
254
255	syscallno = SYS_kevent;
256
257	n = 0;
258	start = time(NULL);
259	while (time(NULL) - start < 120) {
260		if (fork() == 0) {
261			if ((e = pthread_create(&rp, NULL, test, NULL)) != 0)
262				errc(1, e, "pthread_create");
263			usleep(1000);
264			for (j = 0; j < THREADS; j++) {
265				if ((e = pthread_create(&cp[j], NULL, calls,
266				    NULL)) != 0)
267					errc(1, e, "pthread_create");
268			}
269			for (j = 0; j < THREADS; j++)
270				pthread_join(cp[j], NULL);
271			if ((e = pthread_kill(rp, SIGINT)) != 0)
272				errc(1, e, "pthread_kill");
273			_exit(0);
274		}
275		wait(NULL);
276		if (n++ > 5000)
277			break;
278	}
279
280	return (0);
281}
282