Skip to content

fix(sqlite): isolate native SQLite symbols from host apps - #532

Draft
VanshKhanna wants to merge 1 commit into
mainfrom
codex/isolate-native-sqlite
Draft

fix(sqlite): isolate native SQLite symbols from host apps#532
VanshKhanna wants to merge 1 commit into
mainfrom
codex/isolate-native-sqlite

Conversation

@VanshKhanna

Copy link
Copy Markdown

Why

WalletKit's native static library exports and references generic sqlite3_* symbols. When an Apple host also links system SQLite, link order can select the host's unencrypted engine for WalletKit's calls. A synthetic native reproducer against unchanged 0.22.0 produces:

vault db error: sqlite error 101: query returned no rows

The missing row is from PRAGMA cipher: system SQLite does not implement it. Reversing link order selects sqlite3mc but can replace the host's SQLite too. Isolated Rust unit tests do not catch this.

Removing cipher validation is not a fix: a disposable experiment without the check initialized successfully but wrote plaintext SQLite and accepted an incorrect key. No real wallet data was used or inspected.

What

  • Compile the existing checksum-verified sqlite3mc amalgamation with its SQLite API local to one C translation unit. Keep the existing SQLite version and compilation settings.
  • Expose 21 walletkit_sqlite3_* wrappers and bind the existing native Rust FFI to those names. Handles and allocations stay with the engine that created them, independent of host link order.
  • Keep cipher validation, key handling, and on-disk formats unchanged. WASM bindings are unchanged. No dependency upgrades, activity backport, migration, vault deletion, or identity reset is included.
  • Add an opt-in native static-library test host and scripts for debug/release regressions. CI wiring is not included: the available GitHub OAuth credential rejected workflow changes. A maintainer can add both documented commands to the macOS Swift job with a bounded step timeout; until then these link-order tests must be run manually.
  • Document the linkage boundary and the requirement to add a prefixed wrapper for future native FFI functions. This isolates the SQLite API; it does not claim to namespace every third-party crypto symbol in the amalgamation.

Test

Passed locally on this PR's source, with the pinned Rust 1.94.1 toolchain:

  • cargo test -p walletkit-sqlite -p walletkit-db --locked: 10 SQLite tests and 11 database tests pass.
  • bash crates/walletkit-sqlite/examples/test_native_linking.sh: passes.
  • bash crates/walletkit-sqlite/examples/test_native_linking.sh release: passes with the workspace's optimized/LTO profile.
  • cargo clippy -p walletkit-sqlite --all-targets --all-features --locked -- -D warnings: passes.
  • cargo fmt --all -- --check, ShellCheck, and git diff --check: pass.
  • Downstream required make swiftlint-changed: no changed Swift files.

The native tests inspect defined and undefined global archive symbols, link Apple's SQLite before and after WalletKit with dead stripping enabled, and check that the host retains its own engine. They verify encrypted persistence/reopening, wrong-key rejection, and byte preservation after failed wrong-key and plaintext-store opens. All data and keys are synthetic and temporary.

Additional supporting validation, on a separate 0.21.4 activity-backport candidate using the same isolation mechanism, not this PR head: all three release iOS archive slices built; the ARM simulator archive passed an engine-isolation probe in both link orders; a downstream World ID app build succeeded. This does not establish end-to-end account compatibility for this PR.

The local linker emits a nonfatal macOS deployment-target warning (26.5 archive versus 26.0 host); all probes pass. Linux/Android/browser CI and a full Swift build of this PR head remain to be checked.

Risk

Security-sensitive native storage/dependency change; keep this PR draft until deliberate review. Encryption parameters and serialization are not intentionally changed, but this changes which SQLite engine actually executes in host apps.

  • Explicit human acknowledgment and approval for GUARD-01 (cryptography), GUARD-02 (storage preservation), and GUARD-06 (security dependency build/linkage).
  • Assess whether any deployed app previously wrote stores through the wrong engine. Existing plaintext stores are preserved and rejected; this PR does not define a recovery/migration policy. Do not delete or reset them to make initialization succeed.
  • Validate existing encrypted-store upgrade/downgrade behavior and real initialization, proof, and credential-activity flows before distribution.
  • Wire both native regression profiles into macOS CI and verify cross-platform and Swift CI, then use a narrow internal rollout with the previous SDK artifact retained and a tested, data-preserving rollback path. An activity/UI flag cannot undo a shared SDK linkage change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant