xref: /freebsd/tools/test/stress2/misc/syscall4.sh (revision e689e7facd8daac745a7954f4b405e680229de7d)
18a272653SPeter Holm#!/bin/sh
28a272653SPeter Holm
38a272653SPeter Holm#
48a272653SPeter Holm# Copyright (c) 2011-2013 Peter Holm
58a272653SPeter Holm# All rights reserved.
68a272653SPeter Holm#
78a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
88a272653SPeter Holm# modification, are permitted provided that the following conditions
98a272653SPeter Holm# are met:
108a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
118a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
128a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
138a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
148a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
158a272653SPeter Holm#
168a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
178a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
188a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
198a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
208a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
218a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
228a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
238a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
248a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
258a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
268a272653SPeter Holm# SUCH DAMAGE.
278a272653SPeter Holm#
288a272653SPeter Holm
298a272653SPeter Holm# Threaded syscall(2) fuzz test inspired by the iknowthis test suite
308a272653SPeter Holm# by Tavis Ormandy <taviso  cmpxchg8b com>
318a272653SPeter Holm
328a272653SPeter Holm# Usage: syscall4.sh [syscall number]
338a272653SPeter Holm#	Without an argument random syscall numbers are tested.
348a272653SPeter Holm#	With an argument only the specified syscall number is tested.
358a272653SPeter Holm
368a272653SPeter Holm# Sample problems found:
378a272653SPeter Holm# Thread stuck in stopprof.
388a272653SPeter Holm# http://people.freebsd.org/~pho/stress/log/kostik732.txt
398a272653SPeter Holm# Fixed by r275121.
408a272653SPeter Holm
418a272653SPeter Holm# panic: td 0xcbe1ac40 is not suspended.
428a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/kostik807.txt
438a272653SPeter Holm# Fixed by r282944.
448a272653SPeter Holm
458a272653SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
468a272653SPeter Holm
478a272653SPeter Holm. ../default.cfg
488a272653SPeter Holm
498a272653SPeter Holmodir=`pwd`
508a272653SPeter Holmcd /tmp
518a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > syscall4.c
528a272653SPeter Holmsed -i '' -e "s#MNTPOINT#$mntpoint#" syscall4.c
538a272653SPeter Holmrm -f /tmp/syscall4
548a272653SPeter Holmmycc -o syscall4 -Wall -Wextra -O2 -g syscall4.c -lpthread || exit 1
558a272653SPeter Holmrm -f syscall4.c
568a272653SPeter Holm
578a272653SPeter Holmkldstat -v | grep -q sysvmsg  || $stress2tools/kldload.sh sysvmsg
588a272653SPeter Holmkldstat -v | grep -q sysvsem  || $stress2tools/kldload.sh sysvsem
598a272653SPeter Holmkldstat -v | grep -q sysvshm  || $stress2tools/kldload.sh sysvshm
608a272653SPeter Holmkldstat -v | grep -q aio      || $stress2tools/kldload.sh aio
618a272653SPeter Holmkldstat -v | grep -q mqueuefs || $stress2tools/kldload.sh mqueuefs
628a272653SPeter Holm
638a272653SPeter Holmmount | grep -q "on $mntpoint " && umount -f $mntpoint
648a272653SPeter Holm[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
658a272653SPeter Holm
668a272653SPeter Holmmdconfig -a -t swap -s 2g -u $mdstart || exit 1
67608c97bfSPeter Holmnewfs $newfs_flags -n md$mdstart > /dev/null
68608c97bfSPeter Holmmount /dev/md$mdstart $mntpoint
698a272653SPeter Holmchmod 777 $mntpoint
708a272653SPeter Holm
718a272653SPeter Holm[ -z "$noswap" ] &&
728a272653SPeter Holm    daemon sh -c "(cd $odir/../testcases/swap; ./swap -t 10m -i 20 -k)" > \
738a272653SPeter Holm    /dev/null
748a272653SPeter Holmsleeptime=${sleeptime:-12}
758a272653SPeter Holmst=`date '+%s'`
768a272653SPeter Holmwhile [ $((`date '+%s'` - st)) -lt $((10 * sleeptime)) ]; do
778a272653SPeter Holm	(cd $mntpoint; /tmp/syscall4 $* 1>>stdout 2>>stderr) &
788a272653SPeter Holm	start=`date '+%s'`
798a272653SPeter Holm	while [ $((`date '+%s'` - start)) -lt $sleeptime ]; do
808a272653SPeter Holm		pgrep syscall4 > /dev/null || break
818a272653SPeter Holm		sleep .5
828a272653SPeter Holm	done
838a272653SPeter Holm	while pkill -9 syscall4; do :; done
848a272653SPeter Holm	wait
858a272653SPeter Holm	ipcs | grep nobody | awk '/^(q|m|s)/ {print " -" $1, $2}' |
868a272653SPeter Holm	    xargs -L 1 ipcrm
878a272653SPeter Holmdone
888a272653SPeter Holmwhile pkill -9 swap; do :; done
898a272653SPeter Holmwhile pkill -9 syscall4; do :; done
908a272653SPeter Holm
918a272653SPeter Holmfor i in `jot 10`; do
92608c97bfSPeter Holm	mount | grep -q md$mdstart  && \
938a272653SPeter Holm		umount $mntpoint && mdconfig -d -u $mdstart && break
948a272653SPeter Holm	sleep 10
958a272653SPeter Holmdone
96608c97bfSPeter Holmif mount | grep -q md$mdstart; then
978a272653SPeter Holm	fstat $mntpoint
988a272653SPeter Holm	echo "umount $mntpoint failed"
998a272653SPeter Holm	exit 1
1008a272653SPeter Holmfi
1018a272653SPeter Holmrm -f /tmp/syscall4
1028a272653SPeter Holmexit 0
1038a272653SPeter HolmEOF
1048a272653SPeter Holm#include <sys/types.h>
1058a272653SPeter Holm#include <sys/event.h>
1068a272653SPeter Holm#include <sys/resource.h>
1078a272653SPeter Holm#include <sys/socket.h>
1088a272653SPeter Holm#include <sys/stat.h>
1098a272653SPeter Holm#include <sys/syscall.h>
1108a272653SPeter Holm#include <sys/wait.h>
1118a272653SPeter Holm
1128a272653SPeter Holm#include <err.h>
1138a272653SPeter Holm#include <errno.h>
1148a272653SPeter Holm#include <fcntl.h>
1158a272653SPeter Holm#include <fts.h>
1168a272653SPeter Holm#include <libutil.h>
1178a272653SPeter Holm#include <pthread.h>
1188a272653SPeter Holm#if defined(__FreeBSD__)
1198a272653SPeter Holm#include <pthread_np.h>
1208a272653SPeter Holm#define	__NP__
1218a272653SPeter Holm#endif
1228a272653SPeter Holm#include <pwd.h>
1238a272653SPeter Holm#include <signal.h>
1248a272653SPeter Holm#include <stdint.h>
1258a272653SPeter Holm#include <stdio.h>
1268a272653SPeter Holm#include <stdlib.h>
1278a272653SPeter Holm#include <string.h>
1288a272653SPeter Holm#include <unistd.h>
1298a272653SPeter Holm
1308a272653SPeter Holmstatic int ignore[] = {
1318a272653SPeter Holm	SYS_syscall,
1328a272653SPeter Holm	SYS_exit,
1338a272653SPeter Holm	SYS_fork,
1348a272653SPeter Holm	11,			/* 11 is obsolete execv */
1358a272653SPeter Holm	SYS_reboot,
1368a272653SPeter Holm	SYS_vfork,
1378a272653SPeter Holm	109,			/* 109 is old sigblock */
1388a272653SPeter Holm	111,			/* 111 is old sigsuspend */
1398a272653SPeter Holm	SYS_shutdown,
1408a272653SPeter Holm	SYS___syscall,
1418a272653SPeter Holm	216,			/* custom syscall */
1428a272653SPeter Holm	SYS_rfork,
1438a272653SPeter Holm	SYS_mac_syscall,
1448a272653SPeter Holm};
1458a272653SPeter Holm
1468a272653SPeter Holmstatic int fd[900], fds[2], kq, socketpr[2];
1478a272653SPeter Holm#ifndef nitems
1488a272653SPeter Holm#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
1498a272653SPeter Holm#endif
1508a272653SPeter Holm#define N 4096
1518a272653SPeter Holm#define MAGIC 1664
1528a272653SPeter Holm#define RUNTIME 120
1538a272653SPeter Holm#define THREADS 50
1548a272653SPeter Holm
1558a272653SPeter Holmstatic uint32_t r[N];
1568a272653SPeter Holmstatic int magic1, syscallno, magic2;
1578a272653SPeter Holm
1588a272653SPeter Holmstatic int
1598a272653SPeter Holmrandom_int(int mi, int ma)
1608a272653SPeter Holm{
1618a272653SPeter Holm        return (arc4random()  % (ma - mi + 1) + mi);
1628a272653SPeter Holm}
1638a272653SPeter Holm
1648a272653SPeter Holmstatic void
1658a272653SPeter Holmhand(int i __unused) {	/* handler */
1668a272653SPeter Holm	exit(1);
1678a272653SPeter Holm}
1688a272653SPeter Holm
1698a272653SPeter Holmstatic unsigned long
1708a272653SPeter Holmmakearg(void)
1718a272653SPeter Holm{
1728a272653SPeter Holm	unsigned int i;
1738a272653SPeter Holm	unsigned long val;
1748a272653SPeter Holm
1758a272653SPeter Holm	val = arc4random();
1768a272653SPeter Holm	i   = arc4random() % 100;
1778a272653SPeter Holm	if (i < 20)
1788a272653SPeter Holm		val = val & 0xff;
1798a272653SPeter Holm	if (i >= 20 && i < 40)
1808a272653SPeter Holm		val = val & 0xffff;
1818a272653SPeter Holm	if (i >= 40 && i < 60)
1828a272653SPeter Holm		val = (unsigned long)(r) | (val & 0xffff);
1838a272653SPeter Holm#if defined(__LP64__)
1848a272653SPeter Holm	if (i >= 60) {
1858a272653SPeter Holm		val = (val << 32) | arc4random();
1868a272653SPeter Holm		if (i > 80)
1878a272653SPeter Holm			val = val & 0x00007fffffffffffUL;
1888a272653SPeter Holm	}
1898a272653SPeter Holm#endif
1908a272653SPeter Holm
1918a272653SPeter Holm	return(val);
1928a272653SPeter Holm}
1938a272653SPeter Holm
1948a272653SPeter Holmstatic void *
1958a272653SPeter Holmtest(void *arg __unused)
1968a272653SPeter Holm{
1978a272653SPeter Holm	FTS *fts;
1988a272653SPeter Holm	FTSENT *p;
1998a272653SPeter Holm	time_t start;
2008a272653SPeter Holm	int ftsoptions, i, numfiles;
2018a272653SPeter Holm	char *args[] = {
2028a272653SPeter Holm	    "/dev",
2038a272653SPeter Holm	    "/proc",
2048a272653SPeter Holm	    "MNTPOINT",
2058a272653SPeter Holm	    "mnt2",
2068a272653SPeter Holm	    ".",
2078a272653SPeter Holm	    NULL,
2088a272653SPeter Holm	};
2098a272653SPeter Holm
2108a272653SPeter Holm#ifdef __NP__
2118a272653SPeter Holm	pthread_set_name_np(pthread_self(), __func__);
2128a272653SPeter Holm#endif
2138a272653SPeter Holm	numfiles = 0;
2148a272653SPeter Holm	ftsoptions = FTS_PHYSICAL;
2158a272653SPeter Holm	start = time(NULL);
2168a272653SPeter Holm	while (time(NULL) - start < 2) {
2178a272653SPeter Holm		for (i = 0; i < N; i++)
2188a272653SPeter Holm			r[i] = arc4random();
2198a272653SPeter Holm
2208a272653SPeter Holm		if (pipe(fds) == -1)
2218a272653SPeter Holm			err(1, "pipe()");
2228a272653SPeter Holm		if (socketpair(PF_UNIX, SOCK_SEQPACKET, 0, socketpr) == -1)
2238a272653SPeter Holm			err(1, "socketpair()");
2248a272653SPeter Holm		kq = kqueue();
2258a272653SPeter Holm
2268a272653SPeter Holm		if ((fts = fts_open(args, ftsoptions, NULL)) == NULL)
2278a272653SPeter Holm			err(1, "fts_open");
2288a272653SPeter Holm
2298a272653SPeter Holm		i = 0;
2308a272653SPeter Holm		while ((p = fts_read(fts)) != NULL) {
2318a272653SPeter Holm			if (fd[i] > 0)
2328a272653SPeter Holm				close(fd[i]);
2338a272653SPeter Holm			if ((fd[i] = open(p->fts_path, O_RDWR)) == -1)
2348a272653SPeter Holm				if ((fd[i] = open(p->fts_path, O_WRONLY)) ==
2358a272653SPeter Holm				    -1)
2368a272653SPeter Holm					if ((fd[i] = open(p->fts_path,
2378a272653SPeter Holm					    O_RDONLY)) == -1)
2388a272653SPeter Holm						continue;
2398a272653SPeter Holm			i++;
2408a272653SPeter Holm			i = i % nitems(fd);
2418a272653SPeter Holm			if (numfiles++ < 10) {
2428a272653SPeter Holm				fprintf(stderr, "%d: pts_path = %s\n",
2438a272653SPeter Holm				    numfiles, p->fts_path);
2448a272653SPeter Holm			}
2458a272653SPeter Holm		}
2468a272653SPeter Holm
2478a272653SPeter Holm		if (fts_close(fts) == -1)
2488a272653SPeter Holm			warn("fts_close()");
2498a272653SPeter Holm		sleep(1);
2508a272653SPeter Holm		close(socketpr[0]);
2518a272653SPeter Holm		close(socketpr[1]);
2528a272653SPeter Holm		close(fds[0]);
2538a272653SPeter Holm		close(fds[1]);
2548a272653SPeter Holm		close(kq);
2558a272653SPeter Holm	}
2568a272653SPeter Holm	return(NULL);
2578a272653SPeter Holm}
2588a272653SPeter Holm
2598a272653SPeter Holmstatic void *
2608a272653SPeter Holmcalls(void *arg __unused)
2618a272653SPeter Holm{
2628a272653SPeter Holm	time_t start;
263*e689e7faSPeter Holm	int i __unused, j, num;
2648a272653SPeter Holm	unsigned long arg1, arg2, arg3, arg4, arg5, arg6, arg7;
2658a272653SPeter Holm
2668a272653SPeter Holm#ifdef __NP__
2678a272653SPeter Holm	pthread_set_name_np(pthread_self(), __func__);
2688a272653SPeter Holm#endif
2698a272653SPeter Holm	start = time(NULL);
2708a272653SPeter Holm	for (i = 0; time(NULL) - start < 10; i++) {
2718a272653SPeter Holm		num = syscallno;
2728a272653SPeter Holm		while (num == 0) {
2738a272653SPeter Holm			num = random_int(0, SYS_MAXSYSCALL);
2748a272653SPeter Holm			for (j = 0; j < (int)nitems(ignore); j++)
2758a272653SPeter Holm				if (num == ignore[j]) {
2768a272653SPeter Holm					num = 0;
2778a272653SPeter Holm					break;
2788a272653SPeter Holm				}
2798a272653SPeter Holm		}
2808a272653SPeter Holm		arg1 = makearg();
2818a272653SPeter Holm		arg2 = makearg();
2828a272653SPeter Holm		arg3 = makearg();
2838a272653SPeter Holm		arg4 = makearg();
2848a272653SPeter Holm		arg5 = makearg();
2858a272653SPeter Holm		arg6 = makearg();
2868a272653SPeter Holm		arg7 = makearg();
2878a272653SPeter Holm
2888a272653SPeter Holm#if 0		/* Debug mode */
2898a272653SPeter Holm		fprintf(stderr, "%2d : syscall(%3d, %lx, %lx, %lx, %lx, %lx,"
2908a272653SPeter Holm		   " %lx, %lx)\n",
2918a272653SPeter Holm			i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
2928a272653SPeter Holm		sleep(2);
2938a272653SPeter Holm#endif
2948a272653SPeter Holm		alarm(1);
2958a272653SPeter Holm		syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
2968a272653SPeter Holm		num = 0;
2978a272653SPeter Holm		if (magic1 != MAGIC || magic2 != MAGIC)
2988a272653SPeter Holm			exit(1);
2998a272653SPeter Holm	}
3008a272653SPeter Holm
3018a272653SPeter Holm	return (NULL);
3028a272653SPeter Holm}
3038a272653SPeter Holm
3048a272653SPeter Holmint
3058a272653SPeter Holmmain(int argc, char **argv)
3068a272653SPeter Holm{
3078a272653SPeter Holm	struct passwd *pw;
3088a272653SPeter Holm	struct rlimit limit;
3098a272653SPeter Holm	pthread_t rp, cp[THREADS];
3108a272653SPeter Holm	time_t start;
3118a272653SPeter Holm	int e, j;
3128a272653SPeter Holm
3138a272653SPeter Holm	magic1 = magic2 = MAGIC;
3148a272653SPeter Holm	if ((pw = getpwnam("nobody")) == NULL)
3158a272653SPeter Holm		err(1, "failed to resolve nobody");
3168a272653SPeter Holm
3178a272653SPeter Holm	if (getenv("USE_ROOT") && argc == 2)
3188a272653SPeter Holm		fprintf(stderr, "Running syscall4 as root for %s.\n",
3198a272653SPeter Holm				argv[1]);
3208a272653SPeter Holm	else {
3218a272653SPeter Holm		if (setgroups(1, &pw->pw_gid) ||
3228a272653SPeter Holm		    setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
3238a272653SPeter Holm		    seteuid(pw->pw_uid) || setuid(pw->pw_uid))
3248a272653SPeter Holm			err(1, "Can't drop privileges to \"nobody\"");
3258a272653SPeter Holm		endpwent();
3268a272653SPeter Holm	}
3278a272653SPeter Holm
3288a272653SPeter Holm	limit.rlim_cur = limit.rlim_max = 1000;
3298a272653SPeter Holm#if defined(RLIMIT_NPTS)
3308a272653SPeter Holm	if (setrlimit(RLIMIT_NPTS, &limit) < 0)
3318a272653SPeter Holm		err(1, "setrlimit");
3328a272653SPeter Holm#endif
3338a272653SPeter Holm
3348a272653SPeter Holm	signal(SIGALRM, hand);
3358a272653SPeter Holm	signal(SIGILL,  hand);
3368a272653SPeter Holm	signal(SIGFPE,  hand);
3378a272653SPeter Holm	signal(SIGSEGV, hand);
3388a272653SPeter Holm	signal(SIGBUS,  hand);
3398a272653SPeter Holm	signal(SIGURG,  hand);
3408a272653SPeter Holm	signal(SIGSYS,  hand);
3418a272653SPeter Holm	signal(SIGTRAP, hand);
3428a272653SPeter Holm
3438a272653SPeter Holm	if (argc > 2) {
3448a272653SPeter Holm		fprintf(stderr, "usage: %s [syscall-num]\n", argv[0]);
3458a272653SPeter Holm		exit(1);
3468a272653SPeter Holm	}
3478a272653SPeter Holm	if (argc == 2) {
3488a272653SPeter Holm		syscallno = atoi(argv[1]);
3498a272653SPeter Holm		for (j = 0; j < (int)nitems(ignore); j++)
3508a272653SPeter Holm			if (syscallno == ignore[j])
3518a272653SPeter Holm				errx(0, "syscall #%d is on the ignore list.",
3528a272653SPeter Holm				    syscallno);
3538a272653SPeter Holm	}
3548a272653SPeter Holm
3558a272653SPeter Holm	if (daemon(1, 1) == -1)
3568a272653SPeter Holm		err(1, "daemon()");
3578a272653SPeter Holm
3588a272653SPeter Holm	system("touch aaa bbb ccc; mkdir -p ddd");
3598a272653SPeter Holm	start = time(NULL);
3608a272653SPeter Holm	while ((time(NULL) - start) < RUNTIME) {
3618a272653SPeter Holm		if (fork() == 0) {
3628a272653SPeter Holm			if ((e = pthread_create(&rp, NULL, test, NULL)) != 0)
3638a272653SPeter Holm				errc(1, e, "pthread_create");
3648a272653SPeter Holm			usleep(1000);
3658a272653SPeter Holm			for (j = 0; j < THREADS; j++)
3668a272653SPeter Holm				if ((e = pthread_create(&cp[j], NULL, calls,
3678a272653SPeter Holm				    NULL)) != 0)
3688a272653SPeter Holm					errc(1, e, "pthread_create");
3698a272653SPeter Holm			for (j = 0; j < THREADS; j++)
3708a272653SPeter Holm				pthread_join(cp[j], NULL);
3718a272653SPeter Holm
3728a272653SPeter Holm			if ((e = pthread_kill(rp, SIGINT)) != 0)
3738a272653SPeter Holm				errc(1, e, "pthread_kill");
3748a272653SPeter Holm			exit(0);
3758a272653SPeter Holm		}
3768a272653SPeter Holm		wait(NULL);
3778a272653SPeter Holm		usleep(10000);
3788a272653SPeter Holm	}
3798a272653SPeter Holm
3808a272653SPeter Holm	return (0);
3818a272653SPeter Holm}
382