From: Ronald Dahlgren Subject: Re: librewolf 153.0.4-1 segfault To: landry@openbsd.org, Ronald Dahlgren Cc: ports@openbsd.org Date: Mon, 24 Aug 2026 15:59:52 +0000 Stuart, Landry, yaydn, and Leah, Thank you for your guidance with how to proceed. I did some digging and was able to identify the root cause and a workaround for the issue. This occurs in both Firefox and Librewolf, although the manifestation is a bit different. In Firefox, I get "Gah" crash tabs for all content but it doesn't dump its core during startup. Content and socket child processes check the rlimit for the number of files. If that number is too low, they try to set a new limit. Neither pledge.content nor pledge.socket has proc, so this is a pledge violation and the kernel kills the process. Normally the parent, which does have proc in pledge.main, raises the limit first and the children inherit something adequate and never call setrlimit at all. Two things have to be true to hit this: the soft limit has to be below whatever the browser wants, and there has to be no headroom under the hard limit for the parent's raise to take effect. Note that 1024/1024 also has no headroom and works fine, so 512 being too low is the other half of it. I have only traced the failing case, so the part about the parent sparing the children is inference. I am using the staff login class. Stock staff sets no openfiles line and inherits openfiles-cur=512 from default, with a hard limit of 1024. My own /etc/login.conf is locally modified and was pinning both the soft and hard limits to 512, which is what removed the headroom. That is probably why this hasn't hit more people: stock ships 512/1024 and works fine. Setting both to 512 reproduces it reliably, and raising the soft limit to 1024 makes it go away. Adding proc to pledge.content and pledge.socket would presumably also avoid the abort, but I haven't tested that, and it would needlessly widen the content sandbox. Skipping the setrlimit when it wouldn't change anything seems like the better fix. This is from a content process, `kdump -f lw.ktrace -p 60048`: 60048 librewolf CALL getrlimit(RLIMIT_NOFILE,0x73c4725c9450) 60048 librewolf STRU struct rlimit { cur=512, max=512 } 60048 librewolf RET getrlimit 0 60048 librewolf CALL setrlimit(RLIMIT_NOFILE,0x73c4725c9450) 60048 librewolf PLDG setrlimit, "proc", errno 1 Operation not permitted 60048 librewolf PSIG SIGABRT SIG_DFL The socket process shows an identical sequence. Here are the pledge records, with the file each process read: 45999 pledge.main stdio rpath wpath cpath inet proc exec prot_exec flock ps sendfd recvfd dns vminfo tty drm unix fattr getpw mcast video route <- has proc, survives 37962 pledge.socket stdio rpath recvfd sendfd inet dns <- aborts 60048 pledge.content stdio rpath wpath cpath recvfd sendfd prot_exec unix drm ps inet dns getpw <- aborts 27325 pledge.rdd stdio rpath cpath wpath recvfd sendfd unix <- exits 0 Sample argv for a socket child, from a separate run: /usr/local/lib/librewolf/librewolf -contentproc -parentBuildID 20260821003545 -prefsHandle 0:29239 -prefMapHandle 1:294854 -ipcHandle 2 -initialChannelId {6b255f3d-0c85-4651-8c76-84ec325f4138} -parentPid 82697 -appDir /usr/local/lib/librewolf/browser 1 socket The parent's SIGSEGV happens after the children abort, and it re-raises to get the core: 45999 librewolf PSIG SIGSEGV caught handler=0xe4a7694acc0 mask=0<> code=SEGV_MAPERR addr=0xd8 trapno=6 45999 librewolf CALL sigaction(SIGSEGV,0xe4a774d7d90,0) 45999 librewolf CALL sigprocmask(SIG_UNBLOCK,0x400) 45999 librewolf CALL thrkill(0,SIGSEGV,0) 45999 librewolf PSIG SIGSEGV SIG_DFL addr=0x0 trapno=0 librewolf-154.0pl2p0 and firefox-154.0p0 are both affected. thunderbird behaves without the issue. The issue can be reproduced with a new profile, in --safe-mode, with cleared cache, and under env -i. Happy to run anything else that would help, or test patches. Ron