No description
  • Scheme 50.1%
  • Shell 26.2%
  • Makefile 12.6%
  • C 10.8%
  • Common Lisp 0.3%
Find a file
2026-07-30 15:47:28 -06:00
.builds ci: set umask 022 in package/verify tasks too (jerbuild creates group-writable cache dirs during pkg operations) 2026-07-22 13:10:58 -06:00
.jerboa Update SQLite repository references 2026-07-19 12:50:22 -06:00
docs Update SQLite repository references 2026-07-19 12:50:22 -06:00
scripts Update SQLite repository references 2026-07-19 12:50:22 -06:00
src fix: close security audit findings 2026-07-11 17:25:20 -06:00
support fix: close security audit findings 2026-07-11 17:25:20 -06:00
tests fix: close security audit findings 2026-07-11 17:25:20 -06:00
.gitignore Security hardening and release readiness 2026-06-23 10:51:35 -06:00
AGENTS.md docs: remove jerboa-emacs restriction 2026-07-30 15:47:28 -06:00
jerboa_sqlite_shim.c fix: close security audit findings 2026-07-11 17:25:20 -06:00
jpkg.sexp Add jpkg packaging 2026-07-21 15:09:27 -06:00
LICENSE Switch to MIT license 2026-07-21 13:42:20 -06:00
Makefile build: add lint target 2026-07-21 11:58:08 -06:00
README.md Update SQLite repository references 2026-07-19 12:50:22 -06:00
SECURITY.md Update SQLite repository references 2026-07-19 12:50:22 -06:00

jerboa-sqlite-ffi

SQLite3 bindings for Jerboa.

Status: experimental. Treat this repository as a native FFI/storage component until the release gates in SECURITY.md and docs/ffi-boundary.md are complete.

Requirements

  • Jerboa jerbuild
  • C compiler
  • SQLite development headers and library
  • pkg-config recommended

On Debian/Ubuntu:

sudo apt-get install build-essential pkg-config sqlite3 libsqlite3-dev

Build And Test

make test
make loader-policy-test
make native-sanitizer-test
make corrupt-db-corpus
make audit
make sqlite-advisory-check
make reproducibility-report
make target-evidence
make release-evidence

make test builds jerboa_sqlite_shim.so, transpiles the Jerboa library, and runs the SQLite regression tests, including deterministic concurrent step/bind/reset/finalize and query/close races. If jerbuild is not installed, the Makefile bootstraps the pinned Jerboa release into .jerboa/bin.

Production binaries should statically link the shim and pre-register jerboa_sqlite_open_bv and the remaining ABI symbols. Dynamic loading is a development-only path: set JERBOA_SQLITE_DEV_NATIVE=1 and set JERBOA_SQLITE_LIB to the exact canonical absolute path of the shim file. The shim and every ancestor must have an expected root/current-user owner and must not be world-writable; privileged processes ignore both variables. Directories, relative paths, symlinks, non-canonical paths, CWD lookup, and bare loader names are rejected. make loader-policy-test exercises those cases in fresh processes.

make native-sanitizer-test runs the deterministic lifecycle races with a UBSan-instrumented shim. It also builds ASan and TSan shims; they run on Linux, while Darwin records compile evidence because injecting those runtimes into the non-sanitized Scheme host is not a supported local configuration.

make corrupt-db-corpus runs a deterministic 512-case storage corpus through the public wrapper API. It records valid database acceptance plus fail-closed behavior for bad magic, truncated headers, invalid page/header metadata, and generated random-byte database images.

make audit records the SQLite version and native linkage for release notes. On Darwin, the Makefile prefers Homebrew SQLite because the Apple /usr/lib SQLite can lag the reviewed production minimum.

make release-evidence writes the local release artifact bundle under dist/release-evidence/, including toolchain identity, native linkage, SQLite compile options, a minimal SBOM manifest, SQLite advisory status, source inputs, hashes, corrupt-database corpus output, and a two-clean-build reproducibility report that also compares repeated corpus output.

Production support is blocked until make target-evidence records a marker-complete proof through JSQLITE_TARGET_PROOF_FILE; production release hosts should set JSQLITE_REQUIRE_TARGET_PROOF=1. The proof covers target SQLite advisory/linkage review, platform CVE/backport review, external storage fuzzing, downstream consumer integration, backup/WAL/SHM artifact handling, and cross-platform smoke. It must not contain database dumps, WAL/SHM contents, secrets, private paths, hostnames, customer data, or raw command output.

Usage

(import (jerboa-sqlite)) ; compatibility module name

(define db (sqlite-open "my.db"))

(sqlite-exec db "CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)")
(sqlite-eval db "INSERT INTO items (name) VALUES (?)" "hello")

(for-each
  (lambda (row)
    (printf "~a ~a~%" (vector-ref row 0) (vector-ref row 1)))
  (sqlite-query db "SELECT id, name FROM items ORDER BY id"))

(sqlite-close db)

Use parameter binding for untrusted values. Plaintext SQLite database files are sensitive local artifacts if they contain credentials, tokens, user data, or private operational records.

API

Function Description
(sqlite-open path) Open database and return an opaque synchronized handle
(sqlite-close db) Reject new calls, drain active calls, finalize statements, and close exactly once
(sqlite-exec db sql) Execute trusted SQL without result rows
(sqlite-eval db sql args...) Execute with bound parameters
(sqlite-query db sql args...) Query with bound parameters; returns list of vectors
(sqlite-prepare db sql) Prepare statement
(sqlite-bind! stmt idx val) Bind parameter
(sqlite-bind-null! stmt idx) Bind SQL NULL
(sqlite-step stmt) Step statement
(sqlite-reset stmt) Reset statement
(sqlite-clear-bindings stmt) Clear statement bindings
(sqlite-column-value stmt col) Read typed column value
(sqlite-columns stmt) Return column names
(sqlite-finalize stmt) Drain active statement calls and finalize exactly once
(sqlite-last-insert-rowid db) Last inserted row ID
(sqlite-changes db) Rows changed by last statement
(sqlite-errmsg db) Last SQLite error message

Security

See SECURITY.md, docs/ffi-boundary.md, docs/sqlite-advisory-review.md, and docs/release-evidence.md.