1#!/bin/sh 2 3# 4# Copyright (c) 2016 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# A fuzz test using random file descriptors with random seeks. 30# "panic: Assertion (cookie & TMPFS_DIRCOOKIE_MASK) == cookie failed": 31# https://people.freebsd.org/~pho/stress/log/kostik922.txt 32# Fixed by r303916. 33 34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 35 36. ../default.cfg 37 38mount | grep -q "on $mntpoint " && umount -f $mntpoint 39mount -o size=1g -t tmpfs tmpfs $mntpoint 40RUNDIR=$mntpoint/stressX 41dir=$RUNDIR 42 43odir=`pwd` 44cd /tmp 45sed '1,/^EOF/d' < $odir/$0 > tmpfs16.c 46rm -f /tmp/tmpfs16 47mycc -o tmpfs16 -Wall -Wextra -O2 -g tmpfs16.c -lpthread || exit 1 48rm -f tmpfs16.c 49 50rm -rf $dir 51mkdir -p $dir 52chmod 777 $dir 53 54cd $dir 55jot 500 | xargs touch 56jot 500 | xargs chmod 666 57cd $odir 58 59(cd /tmp; /tmp/tmpfs16 $dir) 60e=$? 61 62rm -rf $dir 63umount $mntpoint 64 65rm -f /tmp/tmpfs16 66exit $e 67EOF 68#include <sys/param.h> 69#include <sys/resource.h> 70 71#include <err.h> 72#include <errno.h> 73#include <fcntl.h> 74#include <fts.h> 75#include <libutil.h> 76#include <pthread.h> 77#include <pwd.h> 78#include <stdint.h> 79#include <stdio.h> 80#include <stdlib.h> 81#include <string.h> 82#include <unistd.h> 83 84#define N (128 * 1024 / (int)sizeof(u_int32_t)) 85#define RUNTIME 180 86#define THREADS 2 87 88static int fd[900]; 89static u_int32_t r[N]; 90static char *args[2]; 91 92static unsigned long 93makearg(void) 94{ 95 unsigned long val; 96 97 val = arc4random(); 98#if defined(__LP64__) 99 val = (val << 31) | arc4random(); 100 val = val & 0x00007fffffffffffUL; 101#endif 102 103 return(val); 104} 105 106static void * 107test(void *arg __unused) 108{ 109 FTS *fts; 110 FTSENT *p; 111 int ftsoptions, i, n; 112 113 ftsoptions = FTS_PHYSICAL; 114 115 for (;;) { 116 for (i = 0; i < N; i++) 117 r[i] = arc4random(); 118 if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) 119 err(1, "fts_open"); 120 121 i = n = 0; 122 while ((p = fts_read(fts)) != NULL) { 123 if (fd[i] > 0) 124 close(fd[i]); 125 if ((fd[i] = open(p->fts_path, O_RDWR)) == -1) 126 if ((fd[i] = open(p->fts_path, O_WRONLY)) == -1) 127 continue; 128 if (ftruncate(fd[i], 0) != 0) 129 err(1, "ftruncate"); 130 i++; 131 i = i % nitems(fd); 132 } 133 134 if (fts_close(fts) == -1) 135 err(1, "fts_close()"); 136 sleep(1); 137 } 138 return(0); 139} 140 141static void * 142calls(void *arg __unused) 143{ 144 off_t offset; 145 time_t start; 146 int fd2; 147 148 start = time(NULL); 149 while ((time(NULL) - start) < RUNTIME) { 150 fd2 = makearg() % nitems(fd) + 3; 151 offset = makearg(); 152 if (lseek(fd2, offset - 1, SEEK_SET) != -1) { 153 if (write(fd2, "x", 1) != 1) 154 if (errno != EBADF && errno != ENOSPC) 155 warn("write"); 156 } else 157 if (errno != EBADF) 158 warn("lseek"); 159 if (fsync(fd2) == -1) 160 if (errno != EBADF) 161 warn("x"); 162 163 } 164 165 return (0); 166} 167 168int 169main(int argc, char **argv) 170{ 171 struct passwd *pw; 172 pthread_t rp, cp[THREADS]; 173 int e, i; 174 175 if (argc != 2) { 176 fprintf(stderr, "Usage: %s <dir>\n", argv[0]); 177 exit(1); 178 } 179 args[0] = argv[1]; 180 args[1] = 0; 181 182 if ((pw = getpwnam("nobody")) == NULL) 183 err(1, "failed to resolve nobody"); 184 if (setgroups(1, &pw->pw_gid) || 185 setegid(pw->pw_gid) || setgid(pw->pw_gid) || 186 seteuid(pw->pw_uid) || setuid(pw->pw_uid)) 187 err(1, "Can't drop privileges to \"nobody\""); 188 endpwent(); 189 190 if ((e = pthread_create(&rp, NULL, test, NULL)) != 0) 191 errc(1, e, "pthread_create"); 192 usleep(1000); 193 for (i = 0; i < THREADS; i++) 194 if ((e = pthread_create(&cp[i], NULL, calls, NULL)) != 0) 195 errc(1, e, "pthread_create"); 196 for (i = 0; i < THREADS; i++) 197 pthread_join(cp[i], NULL); 198 199 return (0); 200} 201