14d0adee4SPeter Holm#!/bin/sh 24d0adee4SPeter Holm 34d0adee4SPeter Holm# 4*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 54d0adee4SPeter Holm# 64d0adee4SPeter Holm# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org> 74d0adee4SPeter Holm# 84d0adee4SPeter Holm# Redistribution and use in source and binary forms, with or without 94d0adee4SPeter Holm# modification, are permitted provided that the following conditions 104d0adee4SPeter Holm# are met: 114d0adee4SPeter Holm# 1. Redistributions of source code must retain the above copyright 124d0adee4SPeter Holm# notice, this list of conditions and the following disclaimer. 134d0adee4SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 144d0adee4SPeter Holm# notice, this list of conditions and the following disclaimer in the 154d0adee4SPeter Holm# documentation and/or other materials provided with the distribution. 164d0adee4SPeter Holm# 174d0adee4SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 184d0adee4SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 194d0adee4SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 204d0adee4SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 214d0adee4SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 224d0adee4SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 234d0adee4SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 244d0adee4SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 254d0adee4SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 264d0adee4SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 274d0adee4SPeter Holm# SUCH DAMAGE. 284d0adee4SPeter Holm# 294d0adee4SPeter Holm 304d0adee4SPeter Holm# procctl(2) fuzz test 314d0adee4SPeter Holm 324d0adee4SPeter Holmprog=`basename ${0%.sh}` 334d0adee4SPeter Holmcat > /tmp/$prog.c <<EOF 344d0adee4SPeter Holm#include <sys/param.h> 354d0adee4SPeter Holm#include <sys/mman.h> 364d0adee4SPeter Holm#include <sys/procctl.h> 374d0adee4SPeter Holm 384d0adee4SPeter Holm#include <err.h> 394d0adee4SPeter Holm#include <pthread.h> 404d0adee4SPeter Holm#include <signal.h> 414d0adee4SPeter Holm#include <stdio.h> 424d0adee4SPeter Holm#include <stdlib.h> 434d0adee4SPeter Holm#include <time.h> 444d0adee4SPeter Holm#include <unistd.h> 454d0adee4SPeter Holm 464d0adee4SPeter Holmstatic volatile u_int *share; 474d0adee4SPeter Holm 484d0adee4SPeter Holm#define PARALLEL 25 494d0adee4SPeter Holm#define RUNTIME 120 504d0adee4SPeter Holm 514d0adee4SPeter Holmstatic long 524d0adee4SPeter Holmrandom_long(long mi, long ma) 534d0adee4SPeter Holm{ 544d0adee4SPeter Holm return (arc4random() % (ma - mi + 1) + mi); 554d0adee4SPeter Holm} 564d0adee4SPeter Holm 574d0adee4SPeter Holmstatic void 584d0adee4SPeter Holmflip(void *ap, size_t len) 594d0adee4SPeter Holm{ 604d0adee4SPeter Holm unsigned char *cp; 614d0adee4SPeter Holm int byte; 624d0adee4SPeter Holm unsigned char bit, buf, mask, old __unused; 634d0adee4SPeter Holm 644d0adee4SPeter Holm cp = (unsigned char *)ap; 654d0adee4SPeter Holm byte = random_long(0, len); 664d0adee4SPeter Holm bit = random_long(0,7); 674d0adee4SPeter Holm mask = ~(1 << bit); 684d0adee4SPeter Holm buf = cp[byte]; 694d0adee4SPeter Holm old = cp[byte]; 704d0adee4SPeter Holm buf = (buf & mask) | (~buf & ~mask); 714d0adee4SPeter Holm cp[byte] = buf; 724d0adee4SPeter Holm} 734d0adee4SPeter Holm 744d0adee4SPeter Holmstatic void * 754d0adee4SPeter Holmtr(void *arg __unused) 764d0adee4SPeter Holm{ 774d0adee4SPeter Holm usleep(arc4random() % 400); 784d0adee4SPeter Holm 794d0adee4SPeter Holm return (NULL); 804d0adee4SPeter Holm} 814d0adee4SPeter Holm 824d0adee4SPeter Holmstatic void 834d0adee4SPeter Holmtest(void) { 844d0adee4SPeter Holm pthread_t thr; 854d0adee4SPeter Holm struct procctl_reaper_kill killemall; 864d0adee4SPeter Holm pid_t pid; 874d0adee4SPeter Holm time_t start; 884d0adee4SPeter Holm int data[20], e, n, m; 894d0adee4SPeter Holm 904d0adee4SPeter Holm n = m = 0; 914d0adee4SPeter Holm if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1) 924d0adee4SPeter Holm err(EXIT_FAILURE, "Fail to acquire the reaper"); 934d0adee4SPeter Holm start = time(NULL); 944d0adee4SPeter Holm while (time(NULL) - start < RUNTIME) { 954d0adee4SPeter Holm m++; 964d0adee4SPeter Holm share[0] = 0; 974d0adee4SPeter Holm if ((pid = fork()) == 0) { 984d0adee4SPeter Holm e = pthread_create(&thr, NULL, tr, NULL); 994d0adee4SPeter Holm if (e != 0) 1004d0adee4SPeter Holm errc(1, e, "pthread_create"); 1014d0adee4SPeter Holm share[0] = 1; 1024d0adee4SPeter Holm setproctitle("child"); 1034d0adee4SPeter Holm usleep(arc4random() % 200); 1044d0adee4SPeter Holm if (arc4random() % 100 < 2) 1054d0adee4SPeter Holm raise(SIGSEGV); 1064d0adee4SPeter Holm _exit(0); 1074d0adee4SPeter Holm } 1084d0adee4SPeter Holm arc4random_buf(data, sizeof(data)); 1094d0adee4SPeter Holm while (share[0] == 0) 1104d0adee4SPeter Holm usleep(10); 1114d0adee4SPeter Holm killemall.rk_sig = SIGTERM; 1124d0adee4SPeter Holm killemall.rk_flags = 0; 1134d0adee4SPeter Holm flip(&killemall, sizeof(killemall)); 1144d0adee4SPeter Holm if (procctl(P_PID, getpid(), PROC_REAP_KILL, 1154d0adee4SPeter Holm &killemall) == 0) 1164d0adee4SPeter Holm n++; 1174d0adee4SPeter Holm if (waitpid(pid, NULL, 0) != pid) 1184d0adee4SPeter Holm err(1, "waitpid()"); 1194d0adee4SPeter Holm } 1204d0adee4SPeter Holm#if defined(DEBUG) 1214d0adee4SPeter Holm fprintf(stderr, "n = %d out of %d\n", n, m); 1224d0adee4SPeter Holm#endif 1234d0adee4SPeter Holm _exit(0); 1244d0adee4SPeter Holm} 1254d0adee4SPeter Holm 1264d0adee4SPeter Holmint 1274d0adee4SPeter Holmmain(void) { 1284d0adee4SPeter Holm pid_t pids[PARALLEL]; 1294d0adee4SPeter Holm size_t len; 1304d0adee4SPeter Holm int i; 1314d0adee4SPeter Holm 1324d0adee4SPeter Holm len = PAGE_SIZE; 1334d0adee4SPeter Holm if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 1344d0adee4SPeter Holm MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 1354d0adee4SPeter Holm err(1, "mmap"); 1364d0adee4SPeter Holm for (i = 0; i < PARALLEL; i++) { 1374d0adee4SPeter Holm if ((pids[i] = fork()) == 0) 1384d0adee4SPeter Holm test(); 1394d0adee4SPeter Holm } 1404d0adee4SPeter Holm for (i = 0; i < PARALLEL; i++) 1414d0adee4SPeter Holm if (waitpid(pids[i], NULL, 0) != pids[i]) 1424d0adee4SPeter Holm err(1, "waitpid()"); 1434d0adee4SPeter Holm} 1444d0adee4SPeter HolmEOF 1454d0adee4SPeter Holmcc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1 1464d0adee4SPeter Holmrm /tmp/$prog.c 1474d0adee4SPeter Holm 1484d0adee4SPeter Holmhere=`pwd` 1494d0adee4SPeter Holmcd /tmp 1504d0adee4SPeter Holm./$prog; s=$? 1514d0adee4SPeter Holmcd $here 1524d0adee4SPeter Holm 1534d0adee4SPeter Holmrm -f /tmp/$prog /tmp/$prog.core 1544d0adee4SPeter Holmexit $s 155