Skip to content

Fix four regressions since 2726fe5: all-zero salt, mcFindVfs crash, secure memory re-init, Android build - #300

Merged
utelle merged 4 commits into
utelle:mainfrom
SchwarzDigits:fix/regressions-salt-findvfs
Nov 3, 2026
Merged

utelle merged 4 commits into
utelle:mainfrom
SchwarzDigits:fix/regressions-salt-findvfs

Conversation

@mtrossbach

Copy link
Copy Markdown
Contributor

Four fixes for problems that came in after 2726fe5, one commit each. I reproduced all four on 3186f7e; 2726fe5 does not have them.

Generate a random salt for a new database again
Since c969cdf, mcReadDatabaseHeader() returns the zero-filled header buffer for an empty file, and the key generation takes it as the salt. Every new database (chacha20, sqlcipher, aegis, ascon128; PRAGMA key, sqlite3_key, URI key, ATTACH ... KEY) got a salt of 16 zero bytes, so all new databases with the same password had the same key. For an empty file it returns NULL again. The all-zero salt also made a keyless open delete the hot journal of such a database after a crash: opened with the key, 54 of 3000 rows of the interrupted UPDATE were changed, and quick_check reported ok. With the fix the journal is kept and rolled back.

Check the schema name in mcFindVfs
Since c969cdf, mcFindVfs() indexes db->aDb with the result of sqlite3FindDbName() without checking for -1 or a missing btree. sqlite3_key_v2() and sqlite3_rekey_v2() with an unknown schema name or "temp", and sqlite3_backup_init() with "temp" as source, crashed. The key functions return an error again ("Encryption is not supported by the VFS"), and the backup works as before.

Do not wrap the secure memory allocator twice
Since 654feca, mcMemoryShutdown() resets mcSecureMemoryInitialized. After sqlite3_shutdown(), SQLITE_CONFIG_GETMALLOC still returns the secure memory methods, so the next sqlite3_initialize() saved them as the default methods, the allocator called itself, and sqlite3_initialize() did not return (only with SQLITE3MC_SECURE_MEMORY=1). If the secure memory methods are still installed, they are kept now. An allocator configured after the shutdown is wrapped as before.

Remove SQLITE_ENABLE_BATCH_ATOMIC_WRITE from the Android build
packaging/android/Android.mk still set it, which now stops the build with the #error from da92132.

Tests: rekeytest part 8 now checks that two databases created from empty files with the same key get different salts (the existing check only made sure that the header is not the SQLite magic), and that key, rekey and backup for a schema without a database file return without a crash. On 3186f7e the salt check fails and the schema check crashes. With the fixes rekeytest passes.

Testing (macOS arm64, flags from Makefile.am):

  • The SQL scripts from the CI, cryptotest, the four tempfiletest runs, oomtest and rekeytest pass; rekeytest also with SQLITE3MC_SECURE_MEMORY=1.
  • A shutdown and initialize cycle with SQLITE3MC_SECURE_MEMORY=1 completes.
  • The Android build itself was not run.

Since c969cdf, mcReadDatabaseHeader() returns the zero-filled header
buffer for an empty file, and the key generation takes it as the salt.
Every new database got a salt of 16 zero bytes, so all new databases
with the same password had the same key. Return NULL for an empty file
again, so that a random salt is generated.

The all-zero salt also made a keyless open delete the hot journal of
such a database after a crash.

rekeytest now checks that two databases created from empty files with
the same key get different salts.
Since c969cdf, mcFindVfs() indexes db->aDb with the result of
sqlite3FindDbName() without checking for -1 or a missing btree.
sqlite3_key_v2() and sqlite3_rekey_v2() with an unknown schema name or
"temp", and sqlite3_backup_init() with "temp" as source, crashed. The
key functions return an error again, and the backup works as before.

rekeytest checks these calls.
Since 654feca, mcMemoryShutdown() resets mcSecureMemoryInitialized.
After sqlite3_shutdown(), SQLITE_CONFIG_GETMALLOC still returns the
secure memory methods, so the next sqlite3_initialize() saved them as
the default methods, the allocator called itself, and
sqlite3_initialize() did not return (SQLITE3MC_SECURE_MEMORY=1).

If the secure memory methods are still installed, they are kept now.
An allocator configured after the shutdown is wrapped as before.
Since da92132 the option stops the build with #error.
@utelle
utelle merged commit 5a9d89f into utelle:main Nov 3, 2026
13 checks passed
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.

2 participants