Skip to content

Commit 010e65a

Browse files
committed
Normalize error behavior for wrong key when first op tries modifying schema
In previous versions of SQLCipher, if an incorrect key was used and the first operation was a schema change (e.g. CREATE TABLE x(y)) then the error returned up to the application would be SQLITE_NOMEM instead of SQLITE_NOTADB. While this didn't cause any problems or insecurity, the inconsistency of the error codes was undesirable. Instead of immediately returning NULL from sqlite3Codec when a deferred error condition is detected, SQLCipher now returns a zeroed out buffer instead. This basically mirrors the existing failure mode for decryption. The zeroed buffer is detected as invalid upstream and results in a SQLITE_NOTADB error just like what would happen if a SELECT was executed as the first operation with an incorrect key.
1 parent 5dbb5b3 commit 010e65a

3 files changed

Lines changed: 9 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Notable changes to this project are documented in this file.
33

44
## [4.17.0] - (? 2026 - [4.17.0 changes])
5+
- Normalize error behavior for incorrect keys when first operation
6+
attempts to modfiy the schema
57

68
## [4.16.0] - (May 2026 - [4.16.0 changes])
79
- Update baseline to SQLite 3.53.1

src/sqlcipher.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3245,6 +3245,12 @@ static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
32453245
if(ctx->error != SQLITE_OK) {
32463246
sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_CORE, "%s: identified deferred error condition: %d", __func__, rc);
32473247
sqlcipher_codec_ctx_set_error(ctx, ctx->error);
3248+
/* if this is a read, we don't want to return NULL as it will be interpreted as a SQLITE_NOMEM condition,
3249+
* so instead return a zeroed out buffer that will fail the magic header check */
3250+
if(mode == CODEC_READ_OP) {
3251+
sqlcipher_memset(pData, 0, ctx->page_sz);
3252+
out = pData;
3253+
}
32483254
goto cleanup;
32493255
}
32503256

test/sqlcipher-compatibility.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ do_test migrate-failure-not-readable {
12131213
PRAGMA cipher_test_off = fail_migrate;
12141214
PRAGMA cipher_test;
12151215
}]
1216-
} {{ok 1} {1 {out of memory}} 0}
1216+
} {{ok 1} {1 {file is not a database}} 0}
12171217
db close
12181218
file delete -force test.db
12191219

0 commit comments

Comments
 (0)