Skip to content

Commit

Permalink
Fix issues #158, #160, and #162
Browse files Browse the repository at this point in the history
- #158: add check to verify compatibility of source and target database in backup operation
- #160: fix accessing memory out of array bounds
- #162: fix loading/storing misaligned data
  • Loading branch information
utelle committed Jun 3, 2024
1 parent c95bd21 commit 879f4c6
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 16 deletions.
5 changes: 3 additions & 2 deletions scripts/patchsqlite3.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ die() {
# 1) Intercept VFS pragma handling
# 2) Add handling of KEY parameter in ATTACH statements
sed 's/sqlite3_file_control\(.*SQLITE_FCNTL_PRAGMA\)/sqlite3mcFileControlPragma\1/' "$INPUT" \
| sed '/\#endif \/\* SQLITE3\_H \*\//a \ \n\/\* Function prototypes of SQLite3 Multiple Ciphers \*\/\nSQLITE_PRIVATE int sqlite3mcCheckVfs(const char*);\nSQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*);\nSQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**);\nSQLITE_PRIVATE int sqlite3mcHandleMainKey(sqlite3*, const char*);\ntypedef struct PgHdr PgHdrMC;\nSQLITE_PRIVATE void* sqlite3mcPagerCodec(PgHdrMC* pPg);\ntypedef struct Pager PagerMC;\nSQLITE_PRIVATE int sqlite3mcPagerHasCodec(PagerMC* pPager);\nSQLITE_PRIVATE void sqlite3mcInitMemoryMethods();' \
| sed '/\#endif \/\* SQLITE3\_H \*\//a \ \n\/\* Function prototypes of SQLite3 Multiple Ciphers \*\/\nSQLITE_PRIVATE int sqlite3mcCheckVfs(const char*);\nSQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*);\nSQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**);\nSQLITE_PRIVATE int sqlite3mcHandleMainKey(sqlite3*, const char*);\ntypedef struct PgHdr PgHdrMC;\nSQLITE_PRIVATE void* sqlite3mcPagerCodec(PgHdrMC* pPg);\ntypedef struct Pager PagerMC;\nSQLITE_PRIVATE int sqlite3mcPagerHasCodec(PagerMC* pPager);\nSQLITE_PRIVATE void sqlite3mcInitMemoryMethods();\nSQLITE_PRIVATE int sqlite3mcIsBackupSupported(sqlite3*, const char*, sqlite3*, const char*);' \
| sed '/\#define MAX\_PATHNAME 512/c #if SQLITE3MC\_MAX\_PATHNAME \> 512\n#define MAX_PATHNAME SQLITE3MC\_MAX\_PATHNAME\n#else\n#define MAX_PATHNAME 512\n#endif' \
| sed '/pData = pPage->pData;/c \ if( (pData = sqlite3mcPagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;' \
| sed '/pData = p->pData;/c \ if( (pData = sqlite3mcPagerCodec(p))==0 ) return SQLITE_NOMEM;' \
Expand All @@ -26,4 +26,5 @@ sed 's/sqlite3_file_control\(.*SQLITE_FCNTL_PRAGMA\)/sqlite3mcFileControlPragma\
| sed '/sqlite3_free_filename(zOpen);/i \\n \/\* Handle encryption related URI parameters. \*\/\n if( rc==SQLITE_OK ){\n rc = sqlite3mcHandleMainKey(db, zOpen);\n }' \
| sed '/^ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;/a \ if( sqlite3mcPagerHasCodec(pPager) != 0 ) return 0;' \
| sed '/^ }else if( USEFETCH(pPager) ){/c \ }else if( USEFETCH(pPager) && sqlite3mcPagerHasCodec(pPager) == 0 ){' \
| sed '/^ if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));/a \\n \/\* Initialize wrapper for memory management.\*\/\n if( rc==SQLITE_OK ) {\n sqlite3mcInitMemoryMethods();\n }\n'
| sed '/^ if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));/a \\n \/\* Initialize wrapper for memory management.\*\/\n if( rc==SQLITE_OK ) {\n sqlite3mcInitMemoryMethods();\n }\n' \
| sed '/Lock the source database handle./i \ \/\* Check whether databases are compatible with backup \*\/\n if (!sqlite3mcIsBackupSupported(pSrcDb, zSrcDb, pDestDb, zDestDb)){\n sqlite3ErrorWithMsg(pDestDb, SQLITE_ERROR, \"backup is not supported with incompatible source and target databases\");\n return NULL;\n }\n'
2 changes: 1 addition & 1 deletion src/ascon/aead.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ forceinline void ascon_adata(ascon_state_t* s, const uint8_t* ad,
ASCON_P(s, nr);
}
/* domain separation */
s->x[4] ^= 1;
s->x[4] ^= ASCON_DSEP();
ascon_printstate("domain separation", s);
}

Expand Down
14 changes: 4 additions & 10 deletions src/ascon/word.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ typedef union {

#define ASCON_U64TOWORD(x) ASCON_U64BIG(x)
#define ASCON_WORDTOU64(x) ASCON_U64BIG(x)
#define ASCON_LOAD(b, n) ASCON_LOADBYTES(b, n)
#define ASCON_STORE(b, w, n) ASCON_STOREBYTES(b, w, n)

forceinline uint64_t ASCON_ROR(uint64_t x, int n) { return x >> n | x << (-n & 63); }

Expand All @@ -32,6 +34,8 @@ forceinline int ASCON_NOTZERO(uint64_t a, uint64_t b) {

forceinline uint64_t ASCON_PAD(int i) { return 0x80ull << (56 - 8 * i); }

forceinline uint64_t ASCON_DSEP() { return 0x01; }

forceinline uint64_t ASCON_PRFS_MLEN(uint64_t len) { return len << 51; }

forceinline uint64_t ASCON_CLEAR(uint64_t w, int n) {
Expand All @@ -45,16 +49,6 @@ forceinline uint64_t ASCON_MASK(int n) {
return ~0ull >> (64 - 8 * n);
}

forceinline uint64_t ASCON_LOAD(const uint8_t* bytes, int n) {
uint64_t x = *(uint64_t*)bytes & ASCON_MASK(n);
return ASCON_U64TOWORD(x);
}

forceinline void ASCON_STORE(uint8_t* bytes, uint64_t w, int n) {
*(uint64_t*)bytes &= ~ASCON_MASK(n);
*(uint64_t*)bytes |= ASCON_WORDTOU64(w);
}

forceinline uint64_t ASCON_LOADBYTES(const uint8_t* bytes, int n) {
uint64_t x = 0;
memcpy(&x, bytes, n);
Expand Down
6 changes: 3 additions & 3 deletions src/cipher_sqlcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ EncryptPageSQLCipherCipher(void* cipher, int page, unsigned char* data, int len,
int n = len - nReserved;
int offset = (page == 1) ? (sqlCipherCipher->m_legacy != 0) ? 16 : 24 : 0;
int blen;
unsigned char iv[64];
unsigned char iv[128];
int usePlaintextHeader = 0;

/* Check whether a plaintext header should be used */
Expand All @@ -373,10 +373,10 @@ EncryptPageSQLCipherCipher(void* cipher, int page, unsigned char* data, int len,
}

/* Generate nonce (64 bytes) */
memset(iv, 0, 64);
memset(iv, 0, 128);
if (nReserved > 0)
{
chacha20_rng(iv, 64);
chacha20_rng(iv, 128);
}
else
{
Expand Down
23 changes: 23 additions & 0 deletions src/sqlite3mc_vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,29 @@ SQLITE_PRIVATE Codec* sqlite3mcGetMainCodec(sqlite3* db)
return sqlite3mcGetCodec(db, "main");
}

SQLITE_PRIVATE int sqlite3mcIsBackupSupported(sqlite3* pSrc, const char* zSrc, sqlite3* pDest, const char* zDest)
{
int ok = 1;
if (pSrc != pDest)
{
Codec* codecSrc = sqlite3mcGetCodec(pSrc, zSrc);
Codec* codecDest = sqlite3mcGetCodec(pDest, zDest);
if (codecSrc && codecDest)
{
/* Both databases have a codec */
ok = sqlite3mcIsEncrypted(codecSrc) && sqlite3mcIsEncrypted(codecDest) &&
(sqlite3mcGetReadReserved(codecSrc) == sqlite3mcGetWriteReserved(codecDest));
}
else
{
/* At least one database has no codec */
/* Backup supported if both databases are plain databases */
ok = !codecSrc && !codecDest;
}
}
return ok;
}

/*
** Set the codec of the database file with the given database file name.
**
Expand Down
7 changes: 7 additions & 0 deletions src/sqlite3patched.c
Original file line number Diff line number Diff line change
Expand Up @@ -11170,6 +11170,7 @@ SQLITE_PRIVATE void* sqlite3mcPagerCodec(PgHdrMC* pPg);
typedef struct Pager PagerMC;
SQLITE_PRIVATE int sqlite3mcPagerHasCodec(PagerMC* pPager);
SQLITE_PRIVATE void sqlite3mcInitMemoryMethods();
SQLITE_PRIVATE int sqlite3mcIsBackupSupported(sqlite3*, const char*, sqlite3*, const char*);

/******** Begin file sqlite3rtree.h *********/
/*
Expand Down Expand Up @@ -82186,6 +82187,12 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
}
#endif

/* Check whether databases are compatible with backup */
if (!sqlite3mcIsBackupSupported(pSrcDb, zSrcDb, pDestDb, zDestDb)){
sqlite3ErrorWithMsg(pDestDb, SQLITE_ERROR, "backup is not supported with incompatible source and target databases");
return NULL;
}

/* Lock the source database handle. The destination database
** handle is not locked in this routine, but it is locked in
** sqlite3_backup_step(). The user is required to ensure that no
Expand Down

0 comments on commit 879f4c6

Please sign in to comment.