>Synopsis: RLIMIT_CPU doesn't work reliably on mostly idle systems >Category: system >Environment: System : OpenBSD 7.3 Details : OpenBSD 7.3 (GENERIC.MP) #1242: Sat Mar 25 18:04:31 MDT 2023 dera...@octeon.openbsd.org:/usr/src/sys/arch/octeon/compile/GENERIC.MP
Architecture: OpenBSD.octeon Machine : octeon >Description: RLIMIT_CPU doesn't work reliably when few/no syscalls are made on an otherwise idle system (aside from the test process using up CPU). It can take 20-50s to fire SIGKILL with rlim_max=9 (and the SIGXCPU from rlim_cur=1 won't even fire). I can reproduce this on a private amd64 VM and also on gcc231 on GCC compiler farm <https://cfarm.tetaneutral.net/>. I can't reproduce this on a busy system like gcc220 on cfarm, however. >How-To-Repeat: Following is a standalone C program which demonstrates the problem on a mostly idle system: /* * Most reliably reproduced with compiler optimizations disabled: * * cc -o rlimit_cpu -ggdb3 -Wall rlimit_cpu.c * * Neither SIGXCPU (from rlim_cur) nor SIGKILL (from rlim_max) * with RLIMIT_CPU set seem to fire reliably with few syscalls being made. * On an otherwise idle system, it can take many more seconds (20-50s) * than expected when rlim_max=9 (SIGXCPU doesn't even happen). * Best case is 2 seconds for SIGXCPU when rlim_cur=1 on a busy system * which is understandable due to kernel accounting delays. * * I rely on RLIMIT_CPU to protect systems from pathological userspace * code (diff generation, regexps, etc) * * Testing on cfarm <https://cfarm.tetaneutral.net/> machines, * the issue is visible on a mostly-idle 4-core gcc231 mips64 * but doesn't seem to happen on the busy 12-core gcc220 machine * (only 2 seconds for XCPU w/ rlim_cur=1) */ #include <sys/resource.h> #include <assert.h> #include <signal.h> #include <unistd.h> static void sigxcpu(int sig) { write(1, "SIGXCPU\n", 8); _exit(1); } static volatile size_t nr; // volatile to disable optimizations int main(void) { struct rlimit rlim = { .rlim_cur = 1, .rlim_max = 9 }; int rc; signal(SIGXCPU, sigxcpu); rc = setrlimit(RLIMIT_CPU, &rlim); assert(rc == 0); /* * adding some time, times, and write syscalls improve likelyhood of * of rlimit signals firing in a timely manner. writes to /dev/null * seems less-likely to trigger than writes to the terminal or * regular file. */ for (;; nr++) { } return 0; } >Fix: Making more syscalls can workaround the problem, but that's not an option when dealing with userspace-heavy code like pathological regexps. dmesg: OpenBSD 7.3 (GENERIC.MP) #1242: Sat Mar 25 18:04:31 MDT 2023 dera...@octeon.openbsd.org:/usr/src/sys/arch/octeon/compile/GENERIC.MP real mem = 1073741824 (1024MB) avail mem = 1035304960 (987MB) random: good seed from bootblocks mainbus0 at root: board 20300 rev 0.15, model cavium,ubnt_e300 cpu0 at mainbus0: CN70xx/CN71xx CPU rev 0.2 1000 MHz, CN70xx/CN71xx FPU rev 0.0 cpu0: cache L1-I 78KB 39 way D 32KB 32 way, L2 1024KB 8 way cpu1 at mainbus0: CN70xx/CN71xx CPU rev 0.2 1000 MHz, CN70xx/CN71xx FPU rev 0.0 cpu1: cache L1-I 78KB 39 way D 32KB 32 way, L2 1024KB 8 way cpu2 at mainbus0: CN70xx/CN71xx CPU rev 0.2 1000 MHz, CN70xx/CN71xx FPU rev 0.0 cpu2: cache L1-I 78KB 39 way D 32KB 32 way, L2 1024KB 8 way cpu3 at mainbus0: CN70xx/CN71xx CPU rev 0.2 1000 MHz, CN70xx/CN71xx FPU rev 0.0 cpu3: cache L1-I 78KB 39 way D 32KB 32 way, L2 1024KB 8 way clock0 at mainbus0: int 5 octcrypto0 at mainbus0 iobus0 at mainbus0 simplebus0 at iobus0: "soc" "bootbus" at simplebus0 not configured octciu0 at simplebus0 octcib0 at simplebus0: max-bits 23 octcib1 at simplebus0: max-bits 12 octcib2 at simplebus0: max-bits 6 octcib3 at simplebus0: max-bits 15 octcib4 at simplebus0: max-bits 4 octcib5 at simplebus0: max-bits 11 octcib6 at simplebus0: max-bits 11 octgpio0 at simplebus0: 20 pins, xbit 16 octsmi0 at simplebus0 octsmi1 at simplebus0 octpip0 at simplebus0 octgmx0 at octpip0 interface 0 cnmac0 at octgmx0: port 0 SGMII, address e0:63:da:c0:62:27 ukphy0 at cnmac0 phy 4: Generic IEEE 802.3u media interface, rev. 2: OUI 0x0001c1, model 0x000c cnmac1 at octgmx0: port 1 SGMII, address e0:63:da:c0:62:28 ukphy1 at cnmac1 phy 5: Generic IEEE 802.3u media interface, rev. 2: OUI 0x0001c1, model 0x000c cnmac2 at octgmx0: port 2 SGMII, address e0:63:da:c0:62:29 ukphy2 at cnmac2 phy 6: Generic IEEE 802.3u media interface, rev. 2: OUI 0x0001c1, model 0x000c cnmac3 at octgmx0: port 3 SGMII, address e0:63:da:c0:62:2a ukphy3 at cnmac3 phy 7: Generic IEEE 802.3u media interface, rev. 2: OUI 0x0001c1, model 0x000c octsctl0 at simplebus0: disabled octxctl0 at simplebus0: DWC3 rev 0x250a xhci0 at octxctl0, xHCI 1.0 usb0 at xhci0: USB revision 3.0 uhub0 at usb0 configuration 1 interface 0 "Generic xHCI root hub" rev 3.00/1.00 addr 1 octxctl1 at simplebus0: DWC3 rev 0x250a xhci1 at octxctl1, xHCI 1.0 usb1 at xhci1: USB revision 3.0 uhub1 at usb1 configuration 1 interface 0 "Generic xHCI root hub" rev 3.00/1.00 addr 1 "i2c" at simplebus0 not configured "i2c" at simplebus0 not configured com0 at simplebus0: ns16550a, 64 byte fifo com0: console com1 at simplebus0: ns16550a, 64 byte fifo com1: probed fifo depth: 0 bytes octmmc0 at simplebus0 sdmmc0 at octmmc0: 8-bit, mmc high-speed "spi" at simplebus0 not configured "ocla0" at simplebus0 not configured "dma-engine" at simplebus0 not configured "dma-engine" at simplebus0 not configured octrng0 at iobus0 base 0x1400000000000 irq 0 octpcie0 at iobus0: 3 ports octpcie0 port 0: link timeout octpcie0 port 1: reset timeout octpcie0 port 2: reset timeout umass0 at uhub0 port 2 configuration 1 interface 0 "asmedia ASMT1153E" rev 3.00/1.00 addr 2 umass0: using SCSI over Bulk-Only scsibus0 at umass0: 2 targets, initiator 0 sd0 at scsibus0 targ 1 lun 0: <asmedia, ASMT1153E, 0> serial.174c55aa123456789010 sd0: 953869MB, 512 bytes/sector, 1953525168 sectors scsibus1 at sdmmc0: 2 targets, initiator 0 sd1 at scsibus1 targ 1 lun 0: <Kingston, MMC4GB, 0000> removable sd1: 3728MB, 512 bytes/sector, 7634944 sectors vscsi0 at root scsibus2 at vscsi0: 256 targets softraid0 at root scsibus3 at softraid0: 256 targets root on sd0a (12d0a02327a609ac.a) swap on sd0b dump on sd0b WARNING: /mnt was not properly unmounted WARNING: CHECK AND RESET THE DATE! usbdevs: usbdevs: no USB controllers found