Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/sqlcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -1707,12 +1707,14 @@ static void sqlcipher_ctx_set_error(sqlite3 *db, Db *pDb, sqlcipher_ctx *ctx, in
* the flag. Minimally, the caller must hold SQLCIPHER_MUTEX_SHAREDCACHE. If the BtShared is
* active, then the caller should also hold that mutex. It is possible for the BtShared to be unused
* (i.e. pBt->nRef < 1) if an error occurs during init that blocks setup. */
#ifndef SQLITE_OMIT_SHARED_CACHE
assert(
!ctx->shared || (
sqlite3_mutex_held(sqlcipher_mutex(SQLCIPHER_MUTEX_SHAREDCACHE))
&& (ctx->pBt->nRef < 1 || sqlite3_mutex_held(ctx->pBt->mutex))
)
);
#endif
if(ctx->pBt->inTransaction != TRANS_WRITE) {
ctx->pBt->btsFlags |= BTS_READ_ONLY;
}
Expand Down Expand Up @@ -2571,13 +2573,15 @@ static int sqlcipher_ctx_migrate(sqlite3 *db, sqlcipher_ctx *ctx) {
goto cleanup;
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/* if shared cache is enabled block migrate if there is more than 1 open connection because
* concurrent access is not safe. Similar to rekey, count is read without a lock, but that is low risk */
if(ctx->shared && ctx->pBt->nRef > 1) {
sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_CORE, "%s: PRAGMA cipher_migrate may not be run on a shared cache connection", __func__);
rc = SQLITE_MISUSE;
goto cleanup;
}
#endif

if(!(pass = sqlcipher_malloc(pass_sz+1))) {
sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_CORE, "%s: failed to allocate key material storage", __func__);
Expand Down
26 changes: 14 additions & 12 deletions test/sqlcipher-compatibility.test
Original file line number Diff line number Diff line change
Expand Up @@ -1509,19 +1509,21 @@ do_test export-alias-quoting-2 {
db close
file delete -force test.db {"""a test'ing--db"".db".db}

do_test shared-connection-cant-migrate {
file copy -force $sampleDir/sqlcipher-4.0-testkey.db test.db
sqlite_orig db file:test.db?cache=shared
sqlite_orig db2 file:test.db?cache=shared
ifcapable shared_cache {
do_test shared-connection-cant-migrate {
file copy -force $sampleDir/sqlcipher-4.0-testkey.db test.db
sqlite_orig db file:test.db?cache=shared
sqlite_orig db2 file:test.db?cache=shared

execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_migrate;
}

} {ok 21}
db close
file delete -force test.db
execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_migrate;
}

} {ok 21}
db close
file delete -force test.db
}

sqlite3_test_control_pending_byte $old_pending_byte

Expand Down
2 changes: 2 additions & 0 deletions test/sqlcipher-core.test
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,8 @@ foreach mode {delete truncate persist} {
file delete -force test.db
}

ifcapable !shared_cache { finish_test ; return }

foreach mode {delete persist wal} {
# open up a shared cache connection to a database, key it
# and create a schema. Then, open a second shared cache
Expand Down
42 changes: 22 additions & 20 deletions test/sqlcipher-rekey.test
Original file line number Diff line number Diff line change
Expand Up @@ -571,28 +571,30 @@ foreach version {1 2 3 4 5} {

# rekey may not be used if shared cache is enabled because
# application on one connection could not safely block others
do_test connection-shared-cache-no-rekey {
sqlite_orig db file:test.db?cache=shared
sqlite_orig db2 file:test.db?cache=shared

set rc {}

execsql {
PRAGMA key = 'testkey';
CREATE TABLE t1(a,b);
}
ifcapable shared_cache {
do_test connection-shared-cache-no-rekey {
sqlite_orig db file:test.db?cache=shared
sqlite_orig db2 file:test.db?cache=shared

lappend rc [execsql {
SELECT count(*) FROM sqlite_master;
} db2]
set rc {}

lappend rc [catchsql {
PRAGMA rekey = 'testkey2';
}]
} {1 {1 {An error occurred with PRAGMA key or rekey.}}}
db close
db2 close
file delete -force test.db
execsql {
PRAGMA key = 'testkey';
CREATE TABLE t1(a,b);
}

lappend rc [execsql {
SELECT count(*) FROM sqlite_master;
} db2]

lappend rc [catchsql {
PRAGMA rekey = 'testkey2';
}]
} {1 {1 {An error occurred with PRAGMA key or rekey.}}}
db close
db2 close
file delete -force test.db
}

foreach mode {delete wal} {
# create an encrypted database, rekey it, and verify results. The
Expand Down