Fix native bundles on FreeBSD and Linux
ober
26f85c6a2a826a4fb68ff8956362f2f2cf6b57ce
--- a/Makefile +++ b/Makefile @@ -6,6 +6,9 @@ export SOURCE_DATE_EPOCH HOST_UNAME_S := $(shell uname -s) HOST_UNAME_M := $(shell uname -m) HOST_UNAME_O := $(shell uname -o 2>/dev/null || true) +# SQLite is provided by vendored jsqlite. Packet capture remains explicit +# opt-in because rscap 0.3 does not compile with the supported Rust toolchain. +JERBOA_NATIVE_FEATURES ?= full STATIC ?= 0 STATIC_ENABLED := $(filter 1 yes true on,$(STATIC)) CHEZ_BUILD_DIR ?= $(JERBOA_HOME)/build/chez @@ -318,7 +321,7 @@ jerbuild-smoke: jerbuild jerboa: chez build mcp-check lsp-gen jerboa-multicall native-bundle: - cd $(RUST_NATIVE_DIR) && CARGO_TARGET_DIR=target/bundle-native cargo build --locked --release --features full + cd $(RUST_NATIVE_DIR) && CARGO_TARGET_DIR=target/bundle-native cargo build --locked --release --features $(JERBOA_NATIVE_FEATURES) jerboa-multicall: chez native-bundle $(SCHEME) --libdirs $(LIBDIRS) --script support/build-jerboa-multicall.ss @@ -1664,10 +1667,10 @@ NATIVE_TEST_ENV = JERBOA_HOME=$(JERBOA_HOME) JERBOA_DEV_NATIVE=1 JERBOA_NATIVE_L RUST_NATIVE_LIB = $(RUST_NATIVE_DIR)/target/release/libjerboa_native.$(NATIVE_LIB_EXT) $(RUST_NATIVE_LIB): $(RUST_NATIVE_DIR)/src/*.rs $(RUST_NATIVE_DIR)/Cargo.toml - cd $(RUST_NATIVE_DIR) && cargo build --locked --release --features full + cd $(RUST_NATIVE_DIR) && cargo build --locked --release --features $(JERBOA_NATIVE_FEATURES) native: - cd $(RUST_NATIVE_DIR) && cargo build --locked --release --features full + cd $(RUST_NATIVE_DIR) && cargo build --locked --release --features $(JERBOA_NATIVE_FEATURES) cp $(RUST_NATIVE_LIB) lib/ ifeq ($(UNAME_S),Darwin) @# Re-sign ad-hoc so dyld accepts the freshly-copied dylib. --- a/data/error-fixes.sexp +++ b/data/error-fixes.sexp @@ -2725,4 +2725,16 @@ "Trace the failing syscall before changing directory logic. On FreeBSD use arc4random_buf (or getentropy) for cryptographic random bytes; retain the checked O_NOFOLLOW /dev/urandom path only on platforms where it is not a symlink.") ("id" . "freebsd-urandom-nofollow-emlink") ("pattern" . "create private extraction directory: Too many links") - ("type" . "runtime"))) + ("type" . "runtime")) + (("code_example" + . + "# Keep unstable optional backends opt-in rather than in Cargo's normal bundle.\n[features]\nfull = [\"tls\", \"crypto\", \"duckdb_feat\", \"postgres_feat\", \"wasm\"]\npcap = [\"rscap\"]") + ("explanation" + . + "rscap 0.3.1 stores a raw pointer inside its Linux packet ring, so its Sniffer is not Send. Placing Sniffer handles behind a process-wide OnceLock<Mutex<...>> therefore fails the static Sync requirement on supported Rust toolchains.") + ("fix" + . + "Do not enable rscap through the normal/full native bundle until its Sniffer has a sound Send implementation or the wrapper is redesigned for thread-local ownership. Keep packet capture behind an explicit Cargo feature and verify the default native library has no packet-capture symbols.") + ("id" . "rscap-sniffer-not-send-static-registry") + ("pattern" . "cannot be sent between threads safely.*(PacketRxRing|Sniffer)") + ("type" . "rust-compile"))) --- a/jerboa-native-rs/Cargo.toml +++ b/jerboa-native-rs/Cargo.toml @@ -61,8 +61,9 @@ wasm = ["wasmi", "getrandom"] pcap = ["rscap"] spidermonkey = ["mozjs", "mozjs_sys"] -# Full feature set — backward compatible, what jerboa itself uses -full = ["tls", "crypto", "sqlite", "duckdb_feat", "postgres_feat", "wasm", "pcap"] +# Jerboa's native bundle. SQLite comes from vendor/jsqlite; legacy rusqlite and +# packet capture remain available only through explicit `sqlite`/`pcap` features. +full = ["tls", "crypto", "duckdb_feat", "postgres_feat", "wasm"] [target.'cfg(target_os = "linux")'.dependencies] inotify = { version = "0.11", default-features = false } --- a/support/multicall-main.c +++ b/support/multicall-main.c @@ -176,6 +176,13 @@ static int open_secure_cache_root(const char *path) { } static int secure_random_bytes(unsigned char *out, size_t n) { +#if defined(__FreeBSD__) + /* /dev/urandom is a symlink to /dev/random on FreeBSD. Opening it with + * O_NOFOLLOW therefore fails with EMLINK; arc4random_buf is the native + * nonblocking cryptographic entropy API and requires no file descriptor. */ + arc4random_buf(out, n); + return 0; +#else int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW); size_t off = 0; if (fd < 0) return -1; @@ -186,6 +193,7 @@ static int secure_random_bytes(unsigned char *out, size_t n) { off += (size_t)got; } return close(fd); +#endif } static int make_private_temp_dir(int rootfd, char *name, size_t name_size) {