1#!/bin/sh 2 3# 4# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org> 5# 6# SPDX-License-Identifier: BSD-2-Clause 7# 8 9# Based on code from https://syzkaller.appspot.com/text?tag=ReproC&x=15d9baada80000 10# No problems seen 11 12. ../default.cfg 13 14prog=$(basename "$0" .sh) 15odir=`pwd` 16cd /tmp 17sed '1,/^EOF/d' < $odir/$0 > $prog.c 18mycc -o $prog -Wall -Wextra -O0 $prog.c -lpthread || exit 1 19rm -f $prog.c 20 21set -e 22mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint 23[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 24mdconfig -a -t swap -s 2g -u $mdstart 25newfs $newfs_flags md$mdstart > /dev/null 26mount /dev/md$mdstart $mntpoint 27set +e 28 29$odir/../testcases/swap/swap -t 2m -i 10 > /dev/null & 30cd $mntpoint 31/tmp/$prog 32cd $odir 33while pkill swap; do :; done 34wait 35 36for i in `jot 6`; do 37 mount | grep -q "on $mntpoint " || break 38 umount $mntpoint && break || sleep 10 39 [ $i -eq 6 ] && 40 { echo FATAL; fstat -mf $mntpoint; exit 1; } 41done 42mdconfig -d -u $mdstart 43rm -f /tmp/$prog 44exit 0 45 46EOF 47#include <sys/param.h> 48#include <sys/mman.h> 49#include <sys/uio.h> 50#include <sys/wait.h> 51 52#include <err.h> 53#include <errno.h> 54#include <fcntl.h> 55#include <pthread.h> 56#include <stdio.h> 57#include <stdlib.h> 58#include <string.h> 59#include <unistd.h> 60 61#define DEBUG 0 /* 1 to enable */ 62#define THREADS 2 63 64static volatile int go; 65static int fd; 66static char *p, path[128]; 67 68#define ADDR (void *) 0x20000000ul 69#define LEN 0x1000000ul 70 71void * 72thr(void *arg) 73{ 74 struct iovec iov; 75 long n, w; 76 char *p1; 77 78 if (*(int *)arg == 0) { 79 while (go == 0) 80 usleep(100); 81 while (go == 1) { 82 if ((p1 = mmap(ADDR, LEN, PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED) 83 err(1, "mmap() in %s", __func__); 84 usleep(arc4random() % 50); 85 if ((p1 = mmap(ADDR, LEN, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED) 86 err(1, "mmap() in %s", __func__); 87 usleep(arc4random() % 10000); 88 } 89 } else { 90 while (go == 0) 91 usleep(100); 92 n = w = 0; 93 while (go == 1) { 94 iov.iov_base = p; 95 iov.iov_len = 0x100000; 96 if (pwritev(fd, &iov, 1, 0) != -1) 97 w++; 98 n++; 99 } 100 if (DEBUG == 1) 101 fprintf(stderr, "%ld out of %ld writes (%ld%%)\n", w, n, w * 100 / n); 102 } 103 104 105 return (0); 106} 107 108void 109test(void) 110{ 111 pthread_t threads[THREADS]; 112 int nr[THREADS]; 113 int i, r; 114 115 sprintf(path, "mmap.%06d", getpid()); 116 if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1) 117 err(1,"open()"); 118 119 120 if ((p = mmap(ADDR, LEN, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED) 121 err(1, "mmap() in %s", __func__); 122 123 go = 0; 124 for (i = 0; i < THREADS; i++) { 125 nr[i] = i; 126 if ((r = pthread_create(&threads[i], NULL, thr, 127 (void *)&nr[i])) != 0) 128 errc(1, r, "pthread_create()"); 129 } 130 131 go = 1; 132 sleep(60); 133 go = 2; 134 135 for (i = 0; i < THREADS; i++) { 136 if ((r = pthread_join(threads[i], NULL)) != 0) 137 errc(1, r, "pthread_join(%d)", i); 138 } 139 close(fd); 140 if (DEBUG == 0) { 141 if (unlink(path) == -1) 142 err(1, "unlink(%s)", path); 143 } 144 145 _exit(0); 146} 147 148int 149main(void) 150{ 151 pid_t pid; 152 int i; 153 154 for (i = 0; i < 2; i++) { 155 if ((pid = fork()) == 0) 156 test(); 157 if (waitpid(pid, NULL, 0) != pid) 158 err(1, "waitpid()"); 159 } 160} 161