Skip to content

0.13.4 — sealing a row is not erasing it

Choose a tag to compare

@spranab spranab released this 07 Aug 18:52
· 115 commits to main since this release

Completes the remediation begun in 0.13.2. See GHSA-84vx-5fgq-5p59.

If you enabled encryption and ran the 0.13.2 or 0.13.3 migration, upgrade to 0.13.4 and open the database once.

The 0.13.2 migration sealed every pre-fix oplog payload with UPDATE, which writes the ciphertext to a new page and frees the old one — the plaintext survived in the file until that page was reused. Measured on a 111,590-row oplog: after the migration oplog_plaintext_rows() returned 0 while a raw byte scan still found the recorded content. The remedy had the shape of the bug it fixed: a verification surface reporting a guarantee the storage did not provide.

  • The migration now rewrites the database (VACUUM) and truncates the WAL. Order matters — checkpoint-then-vacuum leaves residue in the main file; measured both ways.
  • It logs STARTING (with row count) and COMPLETE (with elapsed), so a large migration reads as progress rather than a hang. Roughly 8s per 100k rows plus the rewrite.
  • oplog_plaintext_rows() now documents that it counts rows, not bytes — a raw byte scan is the only sufficient verification.
  • New test migration_erases_freed_pages_not_merely_live_rows fails with the VACUUM removed and passes with it — the sensitivity demonstrated in the same run.

Independently verified by the yantrikdb-hermes-plugin gate with a two-engine test: the same fixture shows residual plaintext after the 0.13.3 migration and a clean file after 0.13.4. 1822 tests full, 1739 slim, clippy clean.