1*977d8fb9SPeter Holm#!/bin/sh 2*977d8fb9SPeter Holm 3*977d8fb9SPeter Holm# 4*977d8fb9SPeter Holm# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 5*977d8fb9SPeter Holm# 6*977d8fb9SPeter Holm# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org> 7*977d8fb9SPeter Holm# 8*977d8fb9SPeter Holm# Redistribution and use in source and binary forms, with or without 9*977d8fb9SPeter Holm# modification, are permitted provided that the following conditions 10*977d8fb9SPeter Holm# are met: 11*977d8fb9SPeter Holm# 1. Redistributions of source code must retain the above copyright 12*977d8fb9SPeter Holm# notice, this list of conditions and the following disclaimer. 13*977d8fb9SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 14*977d8fb9SPeter Holm# notice, this list of conditions and the following disclaimer in the 15*977d8fb9SPeter Holm# documentation and/or other materials provided with the distribution. 16*977d8fb9SPeter Holm# 17*977d8fb9SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*977d8fb9SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*977d8fb9SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*977d8fb9SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21*977d8fb9SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*977d8fb9SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*977d8fb9SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*977d8fb9SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*977d8fb9SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*977d8fb9SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*977d8fb9SPeter Holm# SUCH DAMAGE. 28*977d8fb9SPeter Holm# 29*977d8fb9SPeter Holm 30*977d8fb9SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 31*977d8fb9SPeter Holm 32*977d8fb9SPeter Holm# Test setrlimit() max file size and ftruncate() 33*977d8fb9SPeter Holm 34*977d8fb9SPeter Holm# Problem seen: 35*977d8fb9SPeter Holm# Testing UFS -O1 36*977d8fb9SPeter Holm# setrlimit: ftruncate(5413) did not fail. limit = 2791 37*977d8fb9SPeter Holm# Testing FFS -U 38*977d8fb9SPeter Holm# setrlimit: ftruncate(9956) did not fail. limit = 7880 39*977d8fb9SPeter Holm# Testing msdosfs 40*977d8fb9SPeter Holm# setrlimit: ftruncate(9033) did not fail. limit = 5884 41*977d8fb9SPeter Holm# Testing tmpfs 42*977d8fb9SPeter Holm# setrlimit: ftruncate(123) did not fail. limit = 86 43*977d8fb9SPeter Holm 44*977d8fb9SPeter Holm. ../default.cfg 45*977d8fb9SPeter Holm 46*977d8fb9SPeter Holmcat > /tmp/setrlimit.c <<EOF 47*977d8fb9SPeter Holm#include <sys/types.h> 48*977d8fb9SPeter Holm#include <sys/resource.h> 49*977d8fb9SPeter Holm#include <sys/stat.h> 50*977d8fb9SPeter Holm 51*977d8fb9SPeter Holm#include <err.h> 52*977d8fb9SPeter Holm#include <errno.h> 53*977d8fb9SPeter Holm#include <fcntl.h> 54*977d8fb9SPeter Holm#include <signal.h> 55*977d8fb9SPeter Holm#include <stdio.h> 56*977d8fb9SPeter Holm#include <stdlib.h> 57*977d8fb9SPeter Holm#include <unistd.h> 58*977d8fb9SPeter Holm 59*977d8fb9SPeter Holmstatic int signals; 60*977d8fb9SPeter Holm 61*977d8fb9SPeter Holmstatic void 62*977d8fb9SPeter Holmhandler(int sig __unused) 63*977d8fb9SPeter Holm{ 64*977d8fb9SPeter Holm#if defined(DEBUG) 65*977d8fb9SPeter Holm fprintf(stderr, "Got signal SIGXFSZ\n"); 66*977d8fb9SPeter Holm#endif 67*977d8fb9SPeter Holm signals++; 68*977d8fb9SPeter Holm} 69*977d8fb9SPeter Holm 70*977d8fb9SPeter Holmvoid 71*977d8fb9SPeter Holmtest(int argc, char *argv[]) 72*977d8fb9SPeter Holm{ 73*977d8fb9SPeter Holm struct rlimit rlim; 74*977d8fb9SPeter Holm rlim_t limit, sz; 75*977d8fb9SPeter Holm struct sigaction act; 76*977d8fb9SPeter Holm long pos; 77*977d8fb9SPeter Holm int e, expected, fd; 78*977d8fb9SPeter Holm char file[] = "setrlimit.file"; 79*977d8fb9SPeter Holm 80*977d8fb9SPeter Holm if (argc != 2) { 81*977d8fb9SPeter Holm fprintf(stderr, "Usage: %s <FS size>\n", argv[0]); 82*977d8fb9SPeter Holm exit(1); 83*977d8fb9SPeter Holm } 84*977d8fb9SPeter Holm expected = signals = 0; 85*977d8fb9SPeter Holm sz = atol(argv[1]); 86*977d8fb9SPeter Holm arc4random_buf(&limit, sizeof(limit)); 87*977d8fb9SPeter Holm if (limit < 0) 88*977d8fb9SPeter Holm limit = -limit; 89*977d8fb9SPeter Holm limit = limit % sz + 1; 90*977d8fb9SPeter Holm rlim.rlim_cur = rlim.rlim_max = limit; 91*977d8fb9SPeter Holm if (setrlimit(RLIMIT_FSIZE, &rlim) == -1) 92*977d8fb9SPeter Holm err(1, "setrlimit(%ld)", limit); 93*977d8fb9SPeter Holm 94*977d8fb9SPeter Holm act.sa_handler = handler; 95*977d8fb9SPeter Holm act.sa_flags = 0; 96*977d8fb9SPeter Holm sigemptyset(&act.sa_mask); 97*977d8fb9SPeter Holm if (sigaction(SIGXFSZ, &act, NULL) != 0) 98*977d8fb9SPeter Holm err(1, "sigaction"); 99*977d8fb9SPeter Holm 100*977d8fb9SPeter Holm if ((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE)) == -1) 101*977d8fb9SPeter Holm err(1, "open(%s)", file); 102*977d8fb9SPeter Holm 103*977d8fb9SPeter Holm e = 0; 104*977d8fb9SPeter Holm arc4random_buf(&pos, sizeof(pos)); 105*977d8fb9SPeter Holm if (pos < 0) 106*977d8fb9SPeter Holm pos = -pos; 107*977d8fb9SPeter Holm pos = pos % (limit * 2); 108*977d8fb9SPeter Holm if (pos > limit) 109*977d8fb9SPeter Holm expected = 1; 110*977d8fb9SPeter Holm if (ftruncate(fd, pos) == -1) { 111*977d8fb9SPeter Holm e = errno; 112*977d8fb9SPeter Holm if (pos <= limit) 113*977d8fb9SPeter Holm errc(1, e, "ftruncate(%ld), limit = %ld", pos, limit); 114*977d8fb9SPeter Holm } else { 115*977d8fb9SPeter Holm if (pos > limit) 116*977d8fb9SPeter Holm errx(1, "ftruncate(%ld) did not fail. limit = %ld", pos, limit); 117*977d8fb9SPeter Holm } 118*977d8fb9SPeter Holm 119*977d8fb9SPeter Holm if (lseek(fd, limit - 1, SEEK_SET) == -1) 120*977d8fb9SPeter Holm err(1, "lseek(limit - 1)"); 121*977d8fb9SPeter Holm if (write(fd, "a", 1) != 1) 122*977d8fb9SPeter Holm err(1, "write() at limit - 1. limit = %ld", limit); 123*977d8fb9SPeter Holm 124*977d8fb9SPeter Holm if (write(fd, "b", 1) != -1) 125*977d8fb9SPeter Holm err(1, "write() at limit. limit = %ld", limit); 126*977d8fb9SPeter Holm expected++; 127*977d8fb9SPeter Holm 128*977d8fb9SPeter Holm /* Partial write test. No signal is expected */ 129*977d8fb9SPeter Holm if (lseek(fd, limit - 1, SEEK_SET) == -1) 130*977d8fb9SPeter Holm err(1, "lseek(limit - 1)"); 131*977d8fb9SPeter Holm if (write(fd, "12", 2) != 1) 132*977d8fb9SPeter Holm err(1, "write() at limit - 1. limit = %ld", limit); 133*977d8fb9SPeter Holm 134*977d8fb9SPeter Holm if (signals != expected) 135*977d8fb9SPeter Holm errx(1, "Expected %d signals, got %d", expected, signals); 136*977d8fb9SPeter Holm 137*977d8fb9SPeter Holm close(fd); 138*977d8fb9SPeter Holm unlink(file); 139*977d8fb9SPeter Holm} 140*977d8fb9SPeter Holm 141*977d8fb9SPeter Holmint 142*977d8fb9SPeter Holmmain(int argc, char *argv[]) 143*977d8fb9SPeter Holm{ 144*977d8fb9SPeter Holm int i; 145*977d8fb9SPeter Holm 146*977d8fb9SPeter Holm for (i = 0; i < 100; i++) 147*977d8fb9SPeter Holm test(argc, argv); 148*977d8fb9SPeter Holm 149*977d8fb9SPeter Holm} 150*977d8fb9SPeter HolmEOF 151*977d8fb9SPeter Holm 152*977d8fb9SPeter Holmhere=`pwd` 153*977d8fb9SPeter Holms=0 154*977d8fb9SPeter Holmcc -o /tmp/setrlimit -Wall -Wextra -O0 -g /tmp/setrlimit.c || exit 1 155*977d8fb9SPeter Holm 156*977d8fb9SPeter Holmmount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint 157*977d8fb9SPeter Holm[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 158*977d8fb9SPeter Holm 159*977d8fb9SPeter Holmecho "Testing UFS -O1" 160*977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart 161*977d8fb9SPeter Holmnewfs -O1 /dev/md$mdstart > /dev/null 162*977d8fb9SPeter Holmmount /dev/md$mdstart $mntpoint 163*977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=1 164*977d8fb9SPeter Holmcd $here 165*977d8fb9SPeter Holmumount $mntpoint 166*977d8fb9SPeter Holmmdconfig -d -u $mdstart 167*977d8fb9SPeter Holm 168*977d8fb9SPeter Holmecho "Testing FFS -U" 169*977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart 170*977d8fb9SPeter Holmnewfs -U /dev/md$mdstart > /dev/null 171*977d8fb9SPeter Holmmount /dev/md$mdstart $mntpoint 172*977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 2)) 173*977d8fb9SPeter Holmcd $here 174*977d8fb9SPeter Holmumount $mntpoint 175*977d8fb9SPeter Holmmdconfig -d -u $mdstart 176*977d8fb9SPeter Holm 177*977d8fb9SPeter Holmecho "Testing msdosfs" 178*977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart 179*977d8fb9SPeter Holmnewfs_msdos -F 32 -b 8192 /dev/md$mdstart > /dev/null 2>&1 180*977d8fb9SPeter Holmmount -t msdosfs /dev/md$mdstart $mntpoint 181*977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 4)) 182*977d8fb9SPeter Holmcd $here 183*977d8fb9SPeter Holmumount $mntpoint 184*977d8fb9SPeter Holmmdconfig -d -u $mdstart 185*977d8fb9SPeter Holm 186*977d8fb9SPeter Holmecho "Testing tmpfs" 187*977d8fb9SPeter Holmmount -o size=20000 -t tmpfs dummy $mntpoint 188*977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 8)) 189*977d8fb9SPeter Holmcd $here 190*977d8fb9SPeter Holmumount $mntpoint 191*977d8fb9SPeter Holm 192*977d8fb9SPeter Holmrm -f /tmp/setrlimit /tmp/setrlimit.c 193*977d8fb9SPeter Holmexit $s 194