Index | Thread | Search

From:
Klemens Nanni <kn@openbsd.org>
Subject:
devel/ruby-ffi failure on arm64 BTI
To:
ports <ports@openbsd.org>
Cc:
Jeremy Evans <jeremy@openbsd.org>
Date:
Sun, 22 Mar 2026 15:51:58 +0000

Download raw body.

Thread
This effectively breaks sysutils/ruby-openfact and thus sysutils/ruby-openvox,
i.e. I am unable to manage my new machine via Puppet.

jca confirmed the minimal reproducer below crashes on his machine (Mac?), too.
It should print "My pid=...".

	$ dmesg | grep -m1 -w -e BTI -e IBT -e PAC
	$ dmesg | grep -m1 -w BT # related?
	cpu0: TLBIOS+IRANGE,TS+AXFLAG,FHM,DP,SM4,SM3,SHA3,RDM,Atomic,CRC32,SHA2+SHA512,SHA1,AES+PMULL,XS,I8MM,DGH,BF16,SPECRES,SB,FRINTTS,LRCPC+LDAPUR,FCMA,JSCVT,DPB+DCCVADP,GPA3,APA3+EPAC2+FPAC+COMBINED,WFXT,ECV+CNTHCTL,ASID16,AFP,PAN+ATS1E1+EPAN,LO,HPDS,VH,HAFDBS,ECBHB,IDS,AT,CSV3,CSV2+SCXT,DIT,AMU,RASv1p1,SVE,AdvSIMD+HP,FP+HP,BT,SSBS+MSR,MTE

	# pkg_add ruby34-ffi
	$ ktrace -di ruby34 /usr/local/lib/ruby/gems/3.4/gems/ffi-1.17.2/samples/getpid.rb
	[ big dump of loaded files ]
	Illegal instruction (core dumped)

	$ kdump | grep BTCFI
	 88448 ruby34   PSIG  SIGILL caught handler=0x221c893fcc mask=0<> code=ILL_BTCFI addr=0x22b6114000 trapno=905969665

	$ egdb -q ruby34{,.core} -batch -ex bt
	[New process 567109]
	[New process 558154]
	Core was generated by `ruby34'.
	Program terminated with signal SIGILL, Illegal instruction.
	#0  thrkill () at /tmp/-:3

	warning: 3      /tmp/-: No such file or directory
	[Current thread is 1 (process 567109)]
	#0  thrkill () at /tmp/-:3
	#1  0x000000221c892528 in ruby_default_signal () from /usr/local/lib/libruby34.so
	#2  0x000000221c759ae0 [PAC] in rb_bug_for_fatal_signal () from /usr/local/lib/libruby34.so
	#3  0x000000221c89401c [PAC] in sigill () from /usr/local/lib/libruby34.so
	#4  <signal handler called>
	#5  0x00000022b6114000 in ?? ()
	#6  0x000000680038c740 in ?? ()
	Backtrace stopped: Cannot access memory at address 0x800000000000001a

Doing the same in C works, though, so it seems like a Ruby specific issue:

	$ cat ffi-getpid.c                                                                                                                                            
	#include <err.h>
	#include <ffi.h>
	#include <stdio.h>
	#include <unistd.h> // pid_t getpid(void);

	int main() {
		ffi_cif cif;
		pid_t result = 0;
		ffi_type *arg_types[0];
		void *arg_values[0];

		ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_sint32, arg_types);
		ffi_call(&cif, FFI_FN(getpid), &result, arg_values);
		printf("%d\n", result);
		return 0;
	}

	$ cc -I/usr/local/include -L/usr/local/lib -lffi -o ffi-getpid{,.c}                            
	ms-r1$ ./ffi-getpid                                                                                                                                                
	54242

Even with USE_NOBTCFI-aarch64=Yes in lang/ruby/3.4 (as well as devel/ruby-ffi
and devel/libffi for good measure) it still fails.

Does this ring a bell for anyone more knowledgable in arm64/BTI/PAC hackery?