Use Jerboa v0.2.8 toolchain
ober
1bfb3edbfccf6323943f66456f37a1638cfb2aca
--- a/.build.yml +++ b/.build.yml @@ -25,8 +25,8 @@ environment: LATEST_SITE: lisp.srht.site LATEST_SUBDIR: /jerboa-browser/latest LATEST_TARBALL: jerboa-browser-linux-amd64.tar.gz - JERBOA_COMMIT: 73176e945f656334b8b1cf0d6b11c6c41f8ba427 - JERBOA_TREE: 5e2ce0ac497d4b93d3a5859a13856fdbb0987ba3 + JERBOA_COMMIT: ae716feb376ce9adefcad65e923ebfd866131947 + JERBOA_TREE: 9fafa4b48f6a4d1c166dc3ae57be720237ee988b sources: - https://git.sr.ht/~lisp/jerboa-browser artifacts: --- a/AGENTS.md +++ b/AGENTS.md @@ -371,7 +371,6 @@ improved versions of the above. When working in a Jerboa project, **ONLY modify files in the current repo** unless the user explicitly names another path. Common sibling repos that exist but must NOT be touched without explicit instruction: -- `~/mine/jerboa-emacs` — **NEVER touch**. Another model owns it. - `~/mine/jerboa-mcp` — Legacy node MCP, superseded. The active MCP server now lives in THIS repo at `mcp/` + `data/`. Don't modify the legacy repo unless told. - `~/mine/jerboa-shell` — Only modify when user explicitly says to work there. - `~/mine/gerbil-mcp` — **NEVER touch**. Deprecated. --- a/Dockerfile.qt +++ b/Dockerfile.qt @@ -15,9 +15,11 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:24.04@sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90 FROM ${BASE_IMAGE} AS builder -ARG JERBOA_VERSION=master -ARG JERBOA_SOURCE_COMMIT=70c14e8e0e0d9f194bbd142e7418d2b546c9c468 -ARG JERBOA_SOURCE_TREE=4e5dbcc94684a7e61187897fa484a54f77c78929 +ARG JERBOA_VERSION=v0.2.8 +ARG JERBOA_SOURCE_URL=https://git.sr.ht/~lisp/jerboa +ARG JERBOA_SOURCE_COMMIT=ae716feb376ce9adefcad65e923ebfd866131947 +ARG JERBOA_SOURCE_TREE=9fafa4b48f6a4d1c166dc3ae57be720237ee988b +ARG JERBOA_SOURCE_NATIVE_FEATURES=tls,crypto,postgres_feat,wasm ARG JBROWSER_SOURCE_COMMIT ARG JBROWSER_SOURCE_TREE ARG APT_SNAPSHOT=20260701T000000Z @@ -59,7 +61,9 @@ RUN sh /tmp/ensure-rust.sh && \ COPY support/ensure-jerboa.sh support/jerboa-release-sha256.txt /tmp/ RUN JERBOA_SOURCE_COMMIT="$JERBOA_SOURCE_COMMIT" \ + JERBOA_SOURCE_URL="$JERBOA_SOURCE_URL" \ JERBOA_SOURCE_TREE="$JERBOA_SOURCE_TREE" \ + JERBOA_NATIVE_FEATURES="$JERBOA_SOURCE_NATIVE_FEATURES" \ sh /tmp/ensure-jerboa.sh "$JERBOA_VERSION" /usr/local/bin && \ command -v jerbuild && \ jerbuild --version && \ --- a/Makefile +++ b/Makefile @@ -1,10 +1,12 @@ # jerbuild bundles Chez Scheme + the jerboa stdlib, so building the browser # entry needs only `jerbuild` + a C compiler. CI uses a pinned project-local # release toolchain; developer machines can still override JERBUILD explicitly. -JERBOA_VERSION ?= master -JERBOA_COMMIT ?= 70c14e8e0e0d9f194bbd142e7418d2b546c9c468 -JERBOA_TREE ?= 4e5dbcc94684a7e61187897fa484a54f77c78929 -JERBOA_BUNDLE_SHA256 ?= ac8587f3b466f7d6d3047b4cafefd9985a08983503a5ad0764d4947cef25e828 +JERBOA_VERSION ?= v0.2.8 +JERBOA_SOURCE_URL ?= https://git.sr.ht/~lisp/jerboa +JERBOA_COMMIT ?= ae716feb376ce9adefcad65e923ebfd866131947 +JERBOA_TREE ?= 9fafa4b48f6a4d1c166dc3ae57be720237ee988b +JERBOA_SOURCE_NATIVE_FEATURES ?= tls,crypto,postgres_feat,wasm +JERBOA_BUNDLE_SHA256 ?= 6e9aae5475dff96e70f4d9710d47d37fa04eee8948775439f2d796ffb7e2ae8c JERBOA_TOOL_DIR ?= $(CURDIR)/.jerboa/bin JERBUILD ?= $(JERBOA_TOOL_DIR)/jerbuild # Recursive on purpose: check-jerbuild may install the pinned local tool before @@ -132,7 +134,7 @@ all: binary check-jerbuild: @if [ "$(JERBUILD)" = "$(JERBOA_TOOL_DIR)/jerbuild" ] && \ { [ ! -x "$(JERBUILD)" ] || [ "$$(cat "$(JERBOA_TOOL_DIR)/.jerboa-version" 2>/dev/null || true)" != "$(JERBOA_VERSION)" ]; }; then \ - JERBOA_SOURCE_COMMIT="$(JERBOA_COMMIT)" JERBOA_SOURCE_TREE="$(JERBOA_TREE)" \ + JERBOA_SOURCE_URL="$(JERBOA_SOURCE_URL)" JERBOA_SOURCE_COMMIT="$(JERBOA_COMMIT)" JERBOA_SOURCE_TREE="$(JERBOA_TREE)" JERBOA_NATIVE_FEATURES="$(JERBOA_SOURCE_NATIVE_FEATURES)" \ sh support/ensure-jerboa.sh "$(JERBOA_VERSION)" "$(JERBOA_TOOL_DIR)"; \ fi @"$(JERBUILD)" --jerboa-home >/dev/null 2>&1 || { echo $(JERBUILD_ERROR) >&2; exit 1; } @@ -148,7 +150,7 @@ ensure-jerboa-tools: echo "=== Using explicit Jerboa toolchain: $(JERBUILD) ==="; \ else \ echo "=== Fetching Jerboa $(JERBOA_VERSION) release tools into $(JERBOA_TOOL_DIR) ==="; \ - JERBOA_SOURCE_COMMIT="$(JERBOA_COMMIT)" JERBOA_SOURCE_TREE="$(JERBOA_TREE)" \ + JERBOA_SOURCE_URL="$(JERBOA_SOURCE_URL)" JERBOA_SOURCE_COMMIT="$(JERBOA_COMMIT)" JERBOA_SOURCE_TREE="$(JERBOA_TREE)" JERBOA_NATIVE_FEATURES="$(JERBOA_SOURCE_NATIVE_FEATURES)" \ sh support/ensure-jerboa.sh "$(JERBOA_VERSION)" "$(JERBOA_TOOL_DIR)"; \ fi @"$(JERBUILD)" --jerboa-home >/dev/null || { \ @@ -419,8 +421,10 @@ podman-static-qt: check-podman $(PODMAN) build $(PODMAN_BUILD_FLAGS) --platform $(PODMAN_PLATFORM) \ --build-arg BASE_IMAGE="$(STATIC_QT_BASE_IMAGE)" \ --build-arg JERBOA_VERSION="$(JERBOA_VERSION)" \ + --build-arg JERBOA_SOURCE_URL="$(JERBOA_SOURCE_URL)" \ --build-arg JERBOA_SOURCE_COMMIT="$(JERBOA_COMMIT)" \ --build-arg JERBOA_SOURCE_TREE="$(JERBOA_TREE)" \ + --build-arg JERBOA_SOURCE_NATIVE_FEATURES="$(JERBOA_SOURCE_NATIVE_FEATURES)" \ --build-arg APT_SNAPSHOT="$(STATIC_QT_APT_SNAPSHOT)" \ --build-arg JBROWSER_SOURCE_COMMIT="$$(git rev-parse HEAD)" \ --build-arg JBROWSER_SOURCE_TREE="$$(git rev-parse 'HEAD^{tree}')" \ --- a/docs/credential-handling.md +++ b/docs/credential-handling.md @@ -31,9 +31,9 @@ PIV-wrapped data-key format used for bookmarks. When disabled, history commands report that history is disabled and no history entries are recorded. Encrypted bookmark and history writes go through `(std os secure-output)`. -The pinned v0.2.7 toolchain ships the upstream module; the browser keeps the +The pinned v0.2.8 toolchain ships the upstream module; the browser keeps the same fail-closed write path when release archives are unavailable by building -that exact v0.2.7 source tree into the project-local `.jerboa/bin` toolchain. +that exact v0.2.8 source tree into the project-local `.jerboa/bin` toolchain. ## Browser Profile Vault --- a/scheme/browser-adblock-test.ss +++ b/scheme/browser-adblock-test.ss @@ -14,7 +14,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-adblock ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers) (browser keymap) (browser minibuffer) (browser commands)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── --- a/scheme/browser-buffers-test.ss +++ b/scheme/browser-buffers-test.ss @@ -14,7 +14,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-buffers ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers)) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers)) ;;; ─── tiny test framework (shared shape with browser-gui-test.ss) ────────── (define *pass* 0) --- a/scheme/browser-commands-test.ss +++ b/scheme/browser-commands-test.ss @@ -16,7 +16,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-commands ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers) (browser keymap) (browser minibuffer) (browser commands)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── --- a/scheme/browser-fuzz-test.ss +++ b/scheme/browser-fuzz-test.ss @@ -5,7 +5,7 @@ ;;; runs enough iterations to catch parser exceptions, timeout loops, and obvious ;;; UTF-8/embedded-control regressions across the Scheme -> C ABI boundary. -(import (scheme) +(import (jerboa prelude unsafe) (scheme) (browser) (browser keymap) (std test fuzz)) --- a/scheme/browser-gui-test.ss +++ b/scheme/browser-gui-test.ss @@ -17,7 +17,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-gui ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser)) +(import (jerboa prelude unsafe) (scheme) (browser)) ;;; ─── tiny test framework (ported from jerboa-emacs test-qt.ss) ──────────── (define *pass* 0) --- a/scheme/browser-hint-test.ss +++ b/scheme/browser-hint-test.ss @@ -11,7 +11,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-hint ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers) (browser keymap) (browser minibuffer) (browser commands)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── --- a/scheme/browser-keymap-test.ss +++ b/scheme/browser-keymap-test.ss @@ -9,7 +9,7 @@ ;;; Run: make test-keymap (or: scheme --script … with JERBOA_HOME set) ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser keymap)) +(import (jerboa prelude unsafe) (scheme) (browser keymap)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── (define *pass* 0) --- a/scheme/browser-keys-test.ss +++ b/scheme/browser-keys-test.ss @@ -14,7 +14,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-keys ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers) (browser keymap) (browser minibuffer) (browser commands)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── --- a/scheme/browser-minibuffer-test.ss +++ b/scheme/browser-minibuffer-test.ss @@ -5,7 +5,7 @@ ;;; Run: make test-minibuffer ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser fuzzy) (browser minibuffer)) +(import (jerboa prelude unsafe) (scheme) (browser fuzzy) (browser minibuffer)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── (define *pass* 0) --- a/scheme/browser-nav-test.ss +++ b/scheme/browser-nav-test.ss @@ -10,7 +10,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-nav ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers) (browser keymap) (browser minibuffer) (browser commands)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── --- a/scheme/browser-pass-test.ss +++ b/scheme/browser-pass-test.ss @@ -14,7 +14,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-pass ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers) (browser keymap) (browser minibuffer) (browser passwords) (browser commands)) ;;; ─── tiny test framework (shared shape with the other test files) ───────── --- a/scheme/browser-polish-test.ss +++ b/scheme/browser-polish-test.ss @@ -9,7 +9,7 @@ ;;; Run: QT_QPA_PLATFORM=offscreen make test-polish ;;; Exits 0 on success, 1 on any failed case. -(import (scheme) (browser) (browser buffers) +(import (jerboa prelude unsafe) (scheme) (browser) (browser buffers) (browser keymap) (browser minibuffer) (browser bookmarks) (browser commands) (browser observability)) --- a/scheme/browser-securestore-test.ss +++ b/scheme/browser-securestore-test.ss @@ -7,7 +7,8 @@ ;;; `make test` (and `make test-securestore`); needs ./lib/libjerboa_native.* ;;; reachable for the Rust crypto backend (a symlink in lib/ provides it). -(import (except (scheme) +(import (jerboa prelude unsafe) + (except (scheme) make-hash-table hash-table? sort sort! printf fprintf path-extension path-absolute? with-input-from-string with-output-to-string iota 1+ 1- partition make-date make-time) --- a/scheme/browser-test.ss +++ b/scheme/browser-test.ss @@ -11,7 +11,7 @@ ;;; (or via the wrapper that sets JERBOA_BROWSER_LIB / libdirs for you). ;;; Exits 0 on success, 1 on any failed check. -(import (scheme) (browser)) +(import (jerboa prelude unsafe) (scheme) (browser)) (define passed 0) (define failed 0) --- a/scheme/browser.ss +++ b/scheme/browser.ss @@ -82,6 +82,13 @@ browser-downloads-snapshot browser-download-count browser-download-cancel! + ;; secure-memory bridge for repo-local std/crypto/secure-mem shim + browser-secure-alloc + browser-secure-free + browser-secure-wipe + browser-secure-random-fill + browser-secure-region-store! + browser-secure-region-load! ;; window / buffer chrome browser-window-open browser-window-close @@ -448,6 +455,12 @@ (define-c-lambda %downloads-snapshot () char-string "jwb_downloads_snapshot") (define-c-lambda %download-count () int "jwb_download_count") (define-c-lambda %download-cancel (uint32) int "jwb_download_cancel") + (define-c-lambda %secure-alloc (size_t) uint64 "jwb_secure_alloc") + (define-c-lambda %secure-free (uint64 size_t) int "jwb_secure_free") + (define-c-lambda %secure-wipe (uint64 size_t) int "jwb_secure_wipe") + (define-c-lambda %secure-random-fill (uint64 size_t) int "jwb_secure_random_fill") + (define-c-lambda %secure-region-store! (uint64 u8* size_t) int "jwb_secure_region_store") + (define-c-lambda %secure-region-load! (u8* uint64 size_t) int "jwb_secure_region_load") ;; window / buffer chrome (browser_window.cpp) (define-c-lambda %win-open () uint64 "jwb_window_open") (define-c-lambda %win-close (uint64) int "jwb_window_close") @@ -526,6 +539,24 @@ (let ((st (%runtime-init))) (if (= st 0) (ok* #t) (err* (string-append "runtime init: " (%last-error)))))) + (def (browser-secure-alloc size) + (%secure-alloc size)) + + (def (browser-secure-free ptr size) + (%secure-free ptr size)) + + (def (browser-secure-wipe ptr size) + (%secure-wipe ptr size)) + + (def (browser-secure-random-fill ptr size) + (%secure-random-fill ptr size)) + + (def (browser-secure-region-store! ptr bv len) + (%secure-region-store! ptr bv len)) + + (def (browser-secure-region-load! bv ptr len) + (%secure-region-load! bv ptr len)) + ;; --- context / view lifecycle ------------------------------------------ (def (browser-open-context caps) (let ((h (%context-open caps))) --- a/scheme/std/crypto/secure-mem.ss +++ b/scheme/std/crypto/secure-mem.ss @@ -1,17 +1,23 @@ #!chezscheme ;;; (std crypto secure-mem) — repo-local compatibility shim. ;;; -;;; The pinned Jerboa v0.2.4 stdlib hardcodes 4 KiB guard pages in its native -;;; secure-memory allocator, which fails on macOS arm64 hosts with larger system -;;; pages. This module preserves the same public API for this repo and delegates -;;; to page-size-aware jwb_secure_* ABI functions in libjerboa_browser. +;;; Jerboa v0.2.8 provides secure-bytevector APIs in this module. This repo keeps +;;; a page-size-aware bridge to libjerboa_browser for macOS arm64 hosts, where +;;; older fixed-page secure-memory allocation failed, and mirrors the v0.2.8 API +;;; on top of that bridge. (library (std crypto secure-mem) (export secure-alloc secure-free secure-wipe secure-random-fill with-secure-region - secure-region? secure-region-pointer secure-region-size) + secure-region? secure-region-pointer secure-region-size + make-secure-bytevector bytevector->secure-bytevector + secure-bytevector? secure-bytevector-length + secure-bytevector-ref secure-bytevector-set! + secure-bytevector->bytevector secure-bytevector-wipe! + secure-bytevector-random-fill! secure-bytevector-free + with-secure-bytevector) (import (except (scheme) make-hash-table hash-table? @@ -26,14 +32,41 @@ (browser)) (defstruct secure-region (pointer size)) + (defstruct %secure-bytevector (region length)) + (def secure-bytevector? %secure-bytevector?) + (def %make-secure-bytevector make-%secure-bytevector) + (def secure-bytevector-region %secure-bytevector-region) + (def secure-bytevector-length %secure-bytevector-length) - (define-c-lambda %secure-alloc (size_t) uint64 "jwb_secure_alloc") - (define-c-lambda %secure-free (uint64 size_t) int "jwb_secure_free") - (define-c-lambda %secure-wipe (uint64 size_t) int "jwb_secure_wipe") - (define-c-lambda %secure-random-fill (uint64 size_t) int "jwb_secure_random_fill") + (def (checked-size who size) + (unless (and (integer? size) (>= size 0)) + (error who "size must be a non-negative integer" size)) + size) + + (def (checked-byte who byte) + (unless (and (integer? byte) (>= byte 0) (<= byte 255)) + (error who "byte must be an integer in [0,255]" byte)) + byte) + + (def (wipe-heap-bytevector! bv) + (when (bytevector? bv) + (let ((n (bytevector-length bv))) + (let loop ((i 0)) + (when (< i n) + (bytevector-u8-set! bv i 0) + (loop (+ i 1))))))) + + (def (checked-index who sbv index) + (let ((len (secure-bytevector-length sbv))) + (unless (and (integer? index) (>= index 0) (< index len)) + (error who "index out of bounds" index len)) + index)) (def (secure-alloc size) - (let ((ptr (%secure-alloc size))) + (checked-size 'secure-alloc size) + (when (= size 0) + (error 'secure-alloc "size must be greater than zero" size)) + (let ((ptr (browser-secure-alloc size))) (when (= ptr 0) (error 'secure-alloc "secure allocation failed" size)) (make-secure-region ptr size))) @@ -42,7 +75,7 @@ (let ((ptr (secure-region-pointer region)) (size (secure-region-size region))) (unless (= ptr 0) - (unless (= 1 (%secure-free ptr size)) + (unless (= 1 (browser-secure-free ptr size)) (error 'secure-free "secure free failed")) (secure-region-pointer-set! region 0) (secure-region-size-set! region 0))) @@ -52,7 +85,7 @@ (let ((ptr (secure-region-pointer region))) (when (= ptr 0) (error 'secure-wipe "secure region has been freed")) - (unless (= 1 (%secure-wipe ptr (secure-region-size region))) + (unless (= 1 (browser-secure-wipe ptr (secure-region-size region))) (error 'secure-wipe "secure wipe failed"))) (void)) @@ -60,10 +93,101 @@ (let ((ptr (secure-region-pointer region))) (when (= ptr 0) (error 'secure-random-fill "secure region has been freed")) - (unless (= 1 (%secure-random-fill ptr (secure-region-size region))) + (unless (= 1 (browser-secure-random-fill ptr (secure-region-size region))) (error 'secure-random-fill "CSPRNG failed"))) (void)) + (def (secure-bytevector-allocation-size len) + (if (= len 0) 1 len)) + + (def (live-region who sbv) + (unless (secure-bytevector? sbv) + (error who "expected secure-bytevector" sbv)) + (let ((region (secure-bytevector-region sbv))) + (when (= (secure-region-pointer region) 0) + (error who "secure bytevector has been freed")) + region)) + + (def (secure-bytevector-load who sbv) + (let* ((region (live-region who sbv)) + (len (secure-bytevector-length sbv)) + (out (make-bytevector len 0))) + (unless (= 1 (browser-secure-region-load! out (secure-region-pointer region) len)) + (error who "could not copy bytes from secure memory")) + out)) + + (def (secure-bytevector-store! who sbv bv) + (let ((region (live-region who sbv)) + (len (bytevector-length bv))) + (unless (= len (secure-bytevector-length sbv)) + (error who "bytevector length mismatch" len (secure-bytevector-length sbv))) + (unless (= 1 (browser-secure-region-store! (secure-region-pointer region) bv len)) + (error who "could not copy bytes into secure memory"))) + (void)) + + (def (make-secure-bytevector size . fill-opt) + (let* ((len (checked-size 'make-secure-bytevector size)) + (fill (and (pair? fill-opt) + (checked-byte 'make-secure-bytevector (car fill-opt)))) + (region (secure-alloc (secure-bytevector-allocation-size len))) + (sbv (%make-secure-bytevector region len))) + (when fill + (let ((tmp (make-bytevector len fill))) + (dynamic-wind + (lambda () #f) + (lambda () + (secure-bytevector-store! 'make-secure-bytevector sbv tmp)) + (lambda () + (wipe-heap-bytevector! tmp))))) + sbv)) + + (def (bytevector->secure-bytevector bv) + (unless (bytevector? bv) + (error 'bytevector->secure-bytevector "expected bytevector" bv)) + (let* ((len (bytevector-length bv)) + (region (secure-alloc (secure-bytevector-allocation-size len))) + (sbv (%make-secure-bytevector region len))) + (if (= 1 (browser-secure-region-store! (secure-region-pointer region) bv len)) + sbv + (begin + (secure-free region) + (error 'bytevector->secure-bytevector "could not copy bytes into secure memory"))))) + + (def (secure-bytevector-ref sbv index) + (let* ((i (checked-index 'secure-bytevector-ref sbv index)) + (tmp (secure-bytevector-load 'secure-bytevector-ref sbv))) + (dynamic-wind + (lambda () #f) + (lambda () + (bytevector-u8-ref tmp i)) + (lambda () + (wipe-heap-bytevector! tmp))))) + + (def (secure-bytevector-set! sbv index byte) + (let* ((i (checked-index 'secure-bytevector-set! sbv index)) + (b (checked-byte 'secure-bytevector-set! byte)) + (tmp (secure-bytevector-load 'secure-bytevector-set! sbv))) + (dynamic-wind + (lambda () #f) + (lambda () + (bytevector-u8-set! tmp i b) + (secure-bytevector-store! 'secure-bytevector-set! sbv tmp)) + (lambda () + (wipe-heap-bytevector! tmp)))) + (void)) + + (def (secure-bytevector->bytevector sbv) + (secure-bytevector-load 'secure-bytevector->bytevector sbv)) + + (def (secure-bytevector-wipe! sbv) + (secure-wipe (live-region 'secure-bytevector-wipe! sbv))) + + (def (secure-bytevector-random-fill! sbv) + (secure-random-fill (live-region 'secure-bytevector-random-fill! sbv))) + + (def (secure-bytevector-free sbv) + (secure-free (live-region 'secure-bytevector-free sbv))) + (define-syntax with-secure-region (syntax-rules () ((_ ((name size) ...) body ...) @@ -74,4 +198,14 @@ (lambda () (secure-free name) ...)))))) + (define-syntax with-secure-bytevector + (syntax-rules () + ((_ ((name size) ...) body ...) + (let ((name (make-secure-bytevector size)) ...) + (dynamic-wind + (lambda () #f) + (lambda () body ...) + (lambda () + (secure-bytevector-free name) ...)))))) + ) ; library (std crypto secure-mem) --- a/scripts/security-check.sh +++ b/scripts/security-check.sh @@ -138,10 +138,10 @@ if ! grep -Eq '^ARG BASE_IMAGE=.*@sha256:[0-9a-f]{64}$' Dockerfile.qt; then fi require_text supply-chain.lock 'jerboa_yubikey.commit=e448afca926ca9ad40fd98effa8d6264cb1019f5' -require_text supply-chain.lock 'jerboa.version=v0.2.7' -require_text supply-chain.lock 'jerboa.commit=73176e945f656334b8b1cf0d6b11c6c41f8ba427' -require_text supply-chain.lock 'jerboa.tree=5e2ce0ac497d4b93d3a5859a13856fdbb0987ba3' -require_text supply-chain.lock 'jerboa.bundle_sha256=ac8587f3b466f7d6d3047b4cafefd9985a08983503a5ad0764d4947cef25e828' +require_text supply-chain.lock 'jerboa.version=v0.2.8' +require_text supply-chain.lock 'jerboa.commit=ae716feb376ce9adefcad65e923ebfd866131947' +require_text supply-chain.lock 'jerboa.tree=9fafa4b48f6a4d1c166dc3ae57be720237ee988b' +require_text supply-chain.lock 'jerboa.bundle_sha256=6e9aae5475dff96e70f4d9710d47d37fa04eee8948775439f2d796ffb7e2ae8c' require_text supply-chain.lock 'jerboa.source_fallback=support/ensure-jerboa.sh' require_text supply-chain.lock 'container.ubuntu_24_04=sha256:' require_text supply-chain.lock 'container.ubuntu_apt_snapshot=20260701T000000Z' --- a/supply-chain.lock +++ b/supply-chain.lock @@ -1,8 +1,8 @@ # jerboa-browser effective release input lock (reviewed 2026-07-10) -jerboa.version=v0.2.7 -jerboa.commit=73176e945f656334b8b1cf0d6b11c6c41f8ba427 -jerboa.tree=5e2ce0ac497d4b93d3a5859a13856fdbb0987ba3 -jerboa.bundle_sha256=ac8587f3b466f7d6d3047b4cafefd9985a08983503a5ad0764d4947cef25e828 +jerboa.version=v0.2.8 +jerboa.commit=ae716feb376ce9adefcad65e923ebfd866131947 +jerboa.tree=9fafa4b48f6a4d1c166dc3ae57be720237ee988b +jerboa.bundle_sha256=6e9aae5475dff96e70f4d9710d47d37fa04eee8948775439f2d796ffb7e2ae8c jerboa.release_checksums=support/jerboa-release-sha256.txt jerboa.source_url=https://git.sr.ht/~lisp/jerboa jerboa.source_fallback=support/ensure-jerboa.sh --- a/support/ensure-jerboa.sh +++ b/support/ensure-jerboa.sh @@ -173,7 +173,11 @@ ensure_source_checkout() { require_tool cargo cache_root=${JERBOA_SOURCE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/jerboa-source} - src_dir="$cache_root/$version-$source_commit" + feature_suffix= + if [ "${JERBOA_NATIVE_FEATURES:-}" ]; then + feature_suffix="-features-$(printf '%s' "$JERBOA_NATIVE_FEATURES" | LC_ALL=C tr -c 'A-Za-z0-9_.=-' '_')" + fi + src_dir="$cache_root/$version-$source_commit$feature_suffix" if [ -d "$src_dir/.git" ]; then verify_source_checkout "$src_dir" --- a/support/jerboa-release-sha256.txt +++ b/support/jerboa-release-sha256.txt @@ -8,3 +8,5 @@ v0.2.4 macos-arm64 2cef9bd20043165e87b318d971411c7c991a20dd61bda40918eeafaf6770e v0.2.4 linux-amd64 c43bc4d49a82baa868353ecadec87765213b1d2a048e24359afe14ca94799419 v0.2.4 linux-arm64 94b8a813e0280b0e33d32088484c7a759e9c3018e384a6efb7c69a5a80d7566d v0.2.4 freebsd-amd64 ba6aff306af1fd2f479c86ce83becd5c3bb0a481a4dc1fe84fa520cc18da56b8 +v0.2.8 macos-arm64 8f1f13fd33c5260e04efba12dec9d4b7cfdfcf0765aa6b39d03eda66e2084daa +v0.2.8 freebsd-amd64 a515152e55474b90e9053c53466d2870c3cbdc9d0f8d5a8b788f067c6ed8e073