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