1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Harden the SQLITE_DBCONFIG_LOOKASIDE interface against misuse, such as

described in [forum:/forumpost/48f365daec|forum post 48f365daec].  Enhancements
to the SQLITE_DBCONFIG_LOOKASIDE documentation.  Test cases in TH3.

FossilOrigin-Name: 1ec4c308c76c69fba031184254fc3340f07607cfbf8342b13713ab445563d377
This commit is contained in:
drh
2025-02-17 14:16:49 +00:00
parent 59c64e086a
commit 56d2fd008b
4 changed files with 76 additions and 44 deletions

View File

@@ -759,17 +759,22 @@ int sqlite3_config(int op, ...){
** If lookaside is already active, return SQLITE_BUSY.
**
** The sz parameter is the number of bytes in each lookaside slot.
** The cnt parameter is the number of slots. If pStart is NULL the
** space for the lookaside memory is obtained from sqlite3_malloc().
** If pStart is not NULL then it is sz*cnt bytes of memory to use for
** the lookaside memory.
** The cnt parameter is the number of slots. If pBuf is NULL the
** space for the lookaside memory is obtained from sqlite3_malloc()
** or similar. If pBuf is not NULL then it is sz*cnt bytes of memory
** to use for the lookaside memory.
*/
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
static int setupLookaside(
sqlite3 *db, /* Database connection being configured */
void *pBuf, /* Memory to use for lookaside. May be NULL */
int sz, /* Desired size of each lookaside memory slot */
int cnt /* Number of slots to allocate */
){
#ifndef SQLITE_OMIT_LOOKASIDE
void *pStart;
sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt;
int nBig; /* Number of full-size slots */
int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */
void *pStart; /* Start of the lookaside buffer */
sqlite3_int64 szAlloc; /* Total space set aside for lookaside memory */
int nBig; /* Number of full-size slots */
int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */
if( sqlite3LookasideUsed(db,0)>0 ){
return SQLITE_BUSY;
@@ -782,17 +787,22 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
sqlite3_free(db->lookaside.pStart);
}
/* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
** than a pointer to be useful.
** than a pointer and small enough to fit in a u16.
*/
sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
sz = ROUNDDOWN8(sz);
if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
if( cnt<0 ) cnt = 0;
if( sz==0 || cnt==0 ){
if( sz>65528 ) sz = 65528;
/* Count must be at least 1 to be useful, but not so large as to use
** more than 0x7fff0000 total bytes for lookaside. */
if( cnt<1 ) cnt = 0;
if( sz>0 && cnt>(0x7fff0000/sz) ) cnt = 0x7fff0000/sz;
szAlloc = (i64)sz*(i64)cnt;
if( szAlloc==0 ){
sz = 0;
pStart = 0;
}else if( pBuf==0 ){
sqlite3BeginBenignMalloc();
pStart = sqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */
pStart = sqlite3Malloc( szAlloc );
sqlite3EndBenignMalloc();
if( pStart ) szAlloc = sqlite3MallocSize(pStart);
}else{
@@ -801,10 +811,10 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
if( sz>=LOOKASIDE_SMALL*3 ){
nBig = szAlloc/(3*LOOKASIDE_SMALL+sz);
nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL;
nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL;
}else if( sz>=LOOKASIDE_SMALL*2 ){
nBig = szAlloc/(LOOKASIDE_SMALL+sz);
nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL;
nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL;
}else
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
if( sz>0 ){