Index: user/pho/stress2/README =================================================================== --- user/pho/stress2/README (revision 295119) +++ user/pho/stress2/README (revision 295120) @@ -1,64 +1,70 @@ $FreeBSD$ This is the FreeBSD kernel stress test suite. The purpose is to crash the computer, by stressing selected parts of the kernel, thus exposing inadequate error handling. -Do not run the syscall test as root. - To build and use: make -sh ./run.sh +sh ./run.sh (see stress2/misc) The "run.sh" script accepts an optional configuration file in order to test specific areas. For example: ./run.sh vfs.cfg To run all of the different test scenarios type: ./run.sh -a You may have to tune the stress test to make sure that your test box run low on resources. For example: INCARNATIONS=125 ./run.sh The following sub-directories exists: ./doc Documentation ./include Include file for building the test programs in ./testcases ./lib Common support files for the test programs ./misc Various test scenarios. Mostly regression tests ./testcases Test programs ./tools Supplementary tools used in stress testing These days most test development occur is stress2/misc, where the regression tests reside. To run all of these tests once, type "./all.sh -o" in the stress2/misc directory. The default mode is to compile tests, but pre-build binaries may be used. See default.cfg for details. + +There may sometimes be a need for running single syscall fuzzing as root. +This can be achieved by setting the environment variable "USE_ROOT", +before running misc/syscall4.sh. For example: +$ ./syscall4.sh 6 +$ USE_ROOT= ./syscall4.sh 6 +Running syscall4 as root for 6. +$ The name stress2 indicates that this is the second generation of the Kernel Stress Test Suite. The first version (stress) was based mostly on scripts. 20090120: des@ pointed out it would be nice to be able to set the random seed in order to be able to reproduce errors in time. A test of this show that the occurrence of panics are still non-deterministic even with a fixed seed. The known broken unionfs was used to test this: http://people.freebsd.org/~pho/stress/log/marcus006.txt. First panic occurred after 29 loops and the second after 8 with a seed of "123". The randomness that is provided by lack of synchronization with timer interrupt, disk block layout and disk access latencies caused by platter and heads speed changes, disk firmware internal operations, and so on are _much_ bigger then the undeterminism caused by the non-repeatable random seed. Anyway, I have always view the this issue as only a slight inconvenience. Index: user/pho/stress2/misc/syscall.sh =================================================================== --- user/pho/stress2/misc/syscall.sh (revision 295119) +++ user/pho/stress2/misc/syscall.sh (nonexistent) @@ -1,60 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2008-2009 Peter Holm -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# - -# Test calls with random arguments, in reverse order -# Old unused test scenario. syscall4.sh replaces this. - -[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 - -. ../default.cfg - -kldstat -v | grep -q sysvmsg || kldload sysvmsg -kldstat -v | grep -q sysvsem || kldload sysvsem -kldstat -v | grep -q sysvshm || kldload sysvshm - -kldstat -v | grep -q aio || kldload aio -kldstat -v | grep -q mqueuefs || kldload mqueuefs - -syscall=`grep SYS_MAXSYSCALL /usr/include/sys/syscall.h | awk '{print $NF}'` - -n=$syscall -[ $# -eq 1 ] && n=$1 - -rm -f /tmp/syscall.log -while [ $n -gt 0 ]; do - echo "`date '+%T'` syscall $n" - echo "`date '+%T'` syscall $n" >> /tmp/syscall.log - for i in `jot 5`; do - su ${testuser} -c "sh -c \"../testcases/syscall/syscall -t 30s -i 100 -h -l 100 -k $n\"" - done - n=$((n - 1)) - chflags -R 0 $RUNDIR - rm -rf $RUNDIR -done Property changes on: user/pho/stress2/misc/syscall.sh ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/pho/stress2/misc/syscall2.sh =================================================================== --- user/pho/stress2/misc/syscall2.sh (revision 295119) +++ user/pho/stress2/misc/syscall2.sh (nonexistent) @@ -1,229 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2009 Peter Holm -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# - -# Test calls with random arguments, in reverse order -# Variation of the syscall test program. -# Old unused test scenario. syscall4.sh replaces this. - -[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 - -. ../default.cfg - -odir=`pwd` -cd /tmp -sed '1,/^EOF/d' < $odir/$0 > syscall2.c -mycc -o syscall2 -Wall -I $odir/../include -L $odir/../lib syscall2.c -lstress -lutil -rm -f syscall2.c - -kldstat -v | grep -q sysvmsg || kldload sysvmsg -kldstat -v | grep -q sysvsem || kldload sysvsem -kldstat -v | grep -q sysvshm || kldload sysvshm - -kldstat -v | grep -q aio || kldload aio -kldstat -v | grep -q mqueuefs || kldload mqueuefs - -syscall=`grep SYS_MAXSYSCALL /usr/include/sys/syscall.h | awk '{print $NF}'` - -n=$syscall -[ $# -eq 1 ] && n=$1 - -rm -f /tmp/syscall2.log -while [ $n -gt 0 ]; do - echo "`date '+%T'` syscall $n" - echo "`date '+%T'` syscall $n" >> /tmp/syscall2.log - for i in `jot 5`; do - su ${testuser} -c "sh -c \"/tmp/syscall2 -t 30s -i 100 -h -l 100 -k $n\"" - done - chflags -R 0 $RUNDIR - rm -rf $RUNDIR - n=$((n - 1)) -done -rm -f /tmp/syscall2 -exit -EOF - -/* Call random system calls with random arguments */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "stress.h" - -static char path[128]; -static int num; -static int starting_dir = 0; -uint32_t rb[7][10]; - -static int ignore[] = { - SYS_syscall, - SYS_exit, - SYS_fork, - 11, /* 11 is obsolete execv */ - SYS_unmount, - SYS_reboot, - SYS_vfork, - 109, /* 109 is old sigblock */ - 111, /* 111 is old sigsuspend */ - SYS_shutdown, - SYS___syscall, - SYS_rfork, - SYS_sigsuspend, - SYS_mac_syscall, - SYS_sigtimedwait, - SYS_sigwaitinfo, -}; - -int -setup(int nb) -{ - int i; - struct rlimit rl; - - umask(0); - sprintf(path,"%s.%05d", getprogname(), getpid()); - (void)mkdir(path, 0770); - if (chdir(path) == -1) - err(1, "chdir(%s), %s:%d", path, __FILE__, __LINE__); - if ((starting_dir = open(".", 0)) < 0) - err(1, "."); - - if (op->argc == 1) { - num = atoi(op->argv[0]); - for (i = 0; i < sizeof(ignore) / sizeof(ignore[0]); i++) - if (num == ignore[i]) { - printf("syscall %d is marked a no test!\n", num); - exit(1); - } - } else { - num = 0; - while (num == 0) { - num = random_int(0, SYS_MAXSYSCALL); - for (i = 0; i < sizeof(ignore) / sizeof(ignore[0]); i++) - if (num == ignore[i]) { - num = 0; - break; - } - } - } - if (op->verbose > 1) - printf("Testing syscall #%d, pid %d\n", num, getpid()); - - /* Multiple parallel core dump may panic the kernel with: - panic: kmem_malloc(184320): kmem_map too small: 84426752 total allocated - */ - rl.rlim_max = rl.rlim_cur = 0; - if (setrlimit(RLIMIT_CORE, &rl) == -1) - warn("setrlimit"); - - setproctitle("#%d", num); - - return (0); -} - -void -cleanup(void) -{ - if (starting_dir != 0) { - if (fchdir(starting_dir) == -1) - err(1, "fchdir()"); - (void)system("find . -type d -exec chmod 777 {} \\;"); - (void)system("find . -type f -exec chmod 666 {} \\;"); - (void)system("find . -delete"); - - if (chdir("..") == -1) - err(1, "chdir(..)"); - if (rmdir(path) == -1) - err(1, "rmdir(%s), %s:%d", path, __FILE__, __LINE__); - } - starting_dir = 0; -} - -void -rainit(void) -{ - int i, j; - - for (i = 0; i < 7; i++) { - for (j = 0; j < 10; j++) { - if (arc4random() % 100 > 20) - rb[i][j] = arc4random(); - else - rb[i][j] = (uint32_t) &rb[i][j]; - } - } -} - -uint32_t -ra(int i) -{ - uint32_t r; - - r = arc4random(); - if ((r & 1) == 0) - r = arc4random(); - else - r = (uint32_t) &rb[i][0]; - - return (r); -} - -int -test(void) -{ - int i; - unsigned int arg1, arg2, arg3, arg4, arg5, arg6, arg7; - - for (i = 0; i < 128; i++) { - rainit(); - arg1 = ra(0); - arg2 = ra(1); - arg3 = ra(2); - arg4 = ra(3); - arg5 = ra(4); - arg6 = ra(5); - arg7 = ra(6); - - if (op->verbose > 3) - printf("%2d : syscall(%3d, %x, %x, %x, %x, %x, %x, %x)\n", - i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - return (0); -} Property changes on: user/pho/stress2/misc/syscall2.sh ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/pho/stress2/misc/syscall3.sh =================================================================== --- user/pho/stress2/misc/syscall3.sh (revision 295119) +++ user/pho/stress2/misc/syscall3.sh (nonexistent) @@ -1,134 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2011 Peter Holm -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# - -# Test random syscalls with random arguments. -# Regression test of r209697 -# Old unused test scenario. syscall4.sh replaces this. - -[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 - -. ../default.cfg - -odir=`pwd` -cd /tmp -sed '1,/^EOF/d' < $odir/$0 > syscall3.c -mycc -o syscall3 -Wall syscall3.c -rm -f syscall3.c - -kldstat -v | grep -q sysvmsg || kldload sysvmsg -kldstat -v | grep -q sysvsem || kldload sysvsem -kldstat -v | grep -q sysvshm || kldload sysvshm - -kldstat -v | grep -q aio || kldload aio -kldstat -v | grep -q mqueuefs || kldload mqueuefs - -mkdir -p $RUNDIR/syscall3 -cd $RUNDIR/syscall3 - -for i in `jot 4`; do - su $testuser -c /tmp/syscall3 & -done -for i in `jot 4`; do - wait -done - -chflags -R 0 $RUNDIR/syscall3 -rm -rf /tmp/syscall3 $RUNDIR/syscall3 -exit -EOF -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int ignore[] = { - SYS_syscall, - SYS_exit, - SYS_fork, - 11, /* 11 is obsolete execv */ - SYS_unmount, - SYS_reboot, - SYS_vfork, - 109, /* 109 is old sigblock */ - 111, /* 111 is old sigsuspend */ - SYS_shutdown, - SYS___syscall, - SYS_rfork, - SYS_sigsuspend, - SYS_mac_syscall, - SYS_sigtimedwait, - SYS_sigwaitinfo, -}; - -void -handler(int i) { - _exit(0); -} - -int -main(int argc, char **argv) -{ - unsigned int i; - unsigned int arg1, arg2, arg3, arg4, arg5, arg6, arg7, num; - - signal(SIGSYS, SIG_IGN); - signal(SIGALRM, handler); - alarm(600); - for (;;) { - num = 0; - while (num == 0) { - num = arc4random(); - for (i = 0; i < sizeof(ignore) / sizeof(ignore[0]); i++) - if (num == ignore[i]) { - num = 0; - break; - } - } - arg1 = arc4random(); - arg2 = arc4random(); - arg3 = arc4random(); - arg4 = arc4random(); - arg5 = arc4random(); - arg6 = arc4random(); - arg7 = arc4random(); - - if (argc > 1) - printf("%2d : syscall(%3d, %x, %x, %x, %x, %x, %x, %x)\n", - i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - return (0); -} Property changes on: user/pho/stress2/misc/syscall3.sh ___________________________________________________________________ Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: user/pho/stress2/misc/syscall4.sh =================================================================== --- user/pho/stress2/misc/syscall4.sh (revision 295119) +++ user/pho/stress2/misc/syscall4.sh (revision 295120) @@ -1,367 +1,368 @@ #!/bin/sh # # Copyright (c) 2011-2013 Peter Holm # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $FreeBSD$ # # Threaded syscall(2) fuzz test inspired by the iknowthis test suite # by Tavis Ormandy # Usage: syscall4.sh [syscall number] # Without an argument random syscall numbers are tested. # With an argument only the specified syscall number is tested. # Sample problems found: # Thread stuck in stopprof. # http://people.freebsd.org/~pho/stress/log/kostik732.txt # Fixed by r275121. # panic: td 0xcbe1ac40 is not suspended. # https://people.freebsd.org/~pho/stress/log/kostik807.txt # Fixed by r282944. [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 . ../default.cfg odir=`pwd` cd /tmp sed '1,/^EOF/d' < $odir/$0 > syscall4.c rm -f /tmp/syscall4 mycc -o syscall4 -Wall -Wextra -O2 -g syscall4.c -lpthread || exit 1 rm -f syscall4.c kldstat -v | grep -q sysvmsg || $odir/../tools/kldload.sh sysvmsg kldstat -v | grep -q sysvsem || $odir/../tools/kldload.sh sysvsem kldstat -v | grep -q sysvshm || $odir/../tools/kldload.sh sysvshm kldstat -v | grep -q aio || $odir/../tools/kldload.sh aio kldstat -v | grep -q mqueuefs || $odir/../tools/kldload.sh mqueuefs mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart mdconfig -a -t swap -s 2g -u $mdstart || exit 1 bsdlabel -w md$mdstart auto newfs $newfs_flags md${mdstart}$part > /dev/null mount /dev/md${mdstart}$part $mntpoint chmod 777 $mntpoint sleeptime=${sleeptime:-12} st=`date '+%s'` while [ $((`date '+%s'` - st)) -lt $((10 * sleeptime)) ]; do daemon sh -c "(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -k -h)" > /dev/null (cd $mntpoint; /tmp/syscall4 $* ) & start=`date '+%s'` while [ $((`date '+%s'` - start)) -lt $sleeptime ]; do pgrep syscall4 > /dev/null || break sleep .5 done while pkill -9 syscall4; do : done wait while pkill -9 swap; do : done ipcs | grep nobody | awk '/^(q|m|s)/ {print " -" $1, $2}' | xargs -L 1 ipcrm done while pkill -9 syscall4; do : done for i in `jot 10`; do mount | grep -q md${mdstart}$part && \ umount $mntpoint && mdconfig -d -u $mdstart && break sleep 10 done if mount | grep -q md${mdstart}$part; then fstat $mntpoint echo "umount $mntpoint failed" exit 1 fi rm -f /tmp/syscall4 exit EOF #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int ignore[] = { SYS_syscall, SYS_exit, SYS_fork, 11, /* 11 is obsolete execv */ SYS_unmount, SYS_reboot, SYS_vfork, 109, /* 109 is old sigblock */ 111, /* 111 is old sigsuspend */ SYS_shutdown, SYS___syscall, 216, /* custom syscall */ SYS_rfork, SYS_sigsuspend, SYS_mac_syscall, SYS_sigtimedwait, SYS_sigwaitinfo, #if __FreeBSD_version < 804500 SYS_thr_create, SYS_thr_new, #endif #if __FreeBSD_version >= 900041 SYS_pdfork, #endif }; int fd[900], fds[2], socketpr[2]; #ifndef nitems #define nitems(x) (sizeof((x)) / sizeof((x)[0])) #endif #define N (128 * 1024 / (int)sizeof(u_int32_t)) #define MAGIC 1664 #define RUNTIME 120 #define THREADS 50 u_int32_t r[N]; int magic1, syscallno, magic2; static int random_int(int mi, int ma) { return (arc4random() % (ma - mi + 1) + mi); } static void hand(int i __unused) { /* handler */ _exit(1); } unsigned long makearg(void) { unsigned int i; unsigned long val; val = arc4random(); i = arc4random() % 100; if (i < 20) val = val & 0xff; if (i >= 20 && i < 40) val = val & 0xffff; if (i >= 40 && i < 60) val = (unsigned long)(r) | (val & 0xffff); #if defined(__LP64__) if (i >= 60) { val = (val << 32) | arc4random(); if (i > 80) val = val & 0x00007fffffffffffUL; } #endif return(val); } void * test(void *arg __unused) { FTS *fts; FTSENT *p; int ftsoptions; char *args[6]; int i; ftsoptions = FTS_PHYSICAL; args[0] = "/dev"; args[1] = "/proc"; args[2] = "/usr/compat/linux/proc"; args[3] = "/ifs"; args[4] = "."; args[5] = 0; for (;;) { for (i = 0; i < N; i++) r[i] = arc4random(); if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) err(1, "fts_open"); i = 0; while ((p = fts_read(fts)) != NULL) { if (fd[i] > 0) close(fd[i]); if ((fd[i] = open(p->fts_path, O_RDWR)) == -1) if ((fd[i] = open(p->fts_path, O_WRONLY)) == -1) if ((fd[i] = open(p->fts_path, O_RDONLY)) == -1) continue; i++; - i = i % 900; + i = i % nitems(fd); } if (fts_close(fts) == -1) err(1, "fts_close()"); if (pipe(fds) == -1) err(1, "pipe()"); if (socketpair(PF_UNIX, SOCK_SEQPACKET, 0, socketpr) == -1) err(1, "socketpair()"); sleep(1); close(socketpr[0]); close(socketpr[1]); close(fds[0]); close(fds[1]); } return(0); } void * calls(void *arg __unused) { int i, j, num; unsigned long arg1, arg2, arg3, arg4, arg5, arg6, arg7; for (i = 0;; i++) { if (i == 0) usleep(1000); num = syscallno; while (num == 0) { num = random_int(0, SYS_MAXSYSCALL); for (j = 0; j < (int)nitems(ignore); j++) if (num == ignore[j]) { num = 0; break; } } arg1 = makearg(); arg2 = makearg(); arg3 = makearg(); arg4 = makearg(); arg5 = makearg(); arg6 = makearg(); arg7 = makearg(); #if 0 /* Debug mode */ fprintf(stderr, "%2d : syscall(%3d, %lx, %lx, %lx, %lx, %lx, %lx, %lx)\n", i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); sleep(2); #endif alarm(1); syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); num = 0; if (magic1 != MAGIC || magic2 != MAGIC) _exit(1); } return (0); } int main(int argc, char **argv) { struct passwd *pw; struct rlimit limit; pthread_t rp, cp[THREADS]; time_t start; int e, j; magic1 = magic2 = MAGIC; if ((pw = getpwnam("nobody")) == NULL) err(1, "no such user: nobody"); - if (getenv("USE_ROOT")) - fprintf(stderr, "Running syscall4 as root.\n"); + if (getenv("USE_ROOT") && argc == 2) + fprintf(stderr, "Running syscall4 as root for %s.\n", + argv[1]); else { if (setgroups(1, &pw->pw_gid) || setegid(pw->pw_gid) || setgid(pw->pw_gid) || seteuid(pw->pw_uid) || setuid(pw->pw_uid)) err(1, "Can't drop privileges to \"nobody\""); endpwent(); } limit.rlim_cur = limit.rlim_max = 1000; #if defined(RLIMIT_NPTS) if (setrlimit(RLIMIT_NPTS, &limit) < 0) err(1, "setrlimit"); #endif signal(SIGALRM, hand); signal(SIGILL, hand); signal(SIGFPE, hand); signal(SIGSEGV, hand); signal(SIGBUS, hand); signal(SIGURG, hand); signal(SIGSYS, hand); signal(SIGTRAP, hand); if (argc > 2) errx(1, "Usage: %s {}", argv[0]); if (argc == 2) { syscallno = atoi(argv[1]); for (j = 0; j < (int)nitems(ignore); j++) if (syscallno == ignore[j]) errx(0, "syscall #%d is on the ignore list.", syscallno); } if (daemon(0, 0) == -1) err(1, "daemon()"); start = time(NULL); while ((time(NULL) - start) < RUNTIME) { if (fork() == 0) { arc4random_stir(); if ((e = pthread_create(&rp, NULL, test, NULL)) != 0) errc(1, e, "pthread_create"); usleep(1000); for (j = 0; j < THREADS; j++) if ((e = pthread_create(&cp[j], NULL, calls, NULL)) != 0) errc(1, e, "pthread_create"); for (j = 0; j < THREADS; j++) pthread_join(cp[j], NULL); _exit(0); } wait(NULL); } return (0); }