1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Prevent the printf formatter from doing large memory allocations - larger

than either the size of the static buffer for interfaces like
sqlite3_snprintf(), or larger than SQLITE_LIMIT_LENGTH for interfaces that
are associated with a database connection.  This helps to prevent DOS
attacks on products that let hostile sources inject arbitrary SQL.  It also
helps fuzzers run faster and more effectively.

FossilOrigin-Name: 179e5d46054e5c86f53a79b7a0823d9a383da8391ad1d3c3b22645927a1e052b
This commit is contained in:
drh
2019-02-01 20:29:04 +00:00
parent 9a6d01bff5
commit 2964225247
3 changed files with 38 additions and 23 deletions

View File

@@ -155,6 +155,27 @@ static char *getTextArg(PrintfArguments *p){
return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
}
/*
** Allocate memory for a temporary buffer needed for printf rendering.
**
** If the requested size of the temp buffer is larger than the size
** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error.
** Do the size check before the memory allocation to prevent rogue
** SQL from requesting large allocations using the precision or width
** field of the printf() function.
*/
static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
char *z;
if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){
setStrAccumError(pAccum, SQLITE_TOOBIG);
return 0;
}
z = sqlite3DbMallocRaw(pAccum->db, n);
if( z==0 ){
setStrAccumError(pAccum, SQLITE_NOMEM);
}
return z;
}
/*
** On machines with a small stack size, you can redefine the
@@ -422,11 +443,8 @@ void sqlite3_str_vappendf(
zOut = buf;
}else{
u64 n = (u64)precision + 10 + precision/3;
zOut = zExtra = sqlite3Malloc( n );
if( zOut==0 ){
setStrAccumError(pAccum, SQLITE_NOMEM);
return;
}
zOut = zExtra = printfTempBuf(pAccum, n);
if( zOut==0 ) return;
nOut = (int)n;
}
bufpt = &zOut[nOut-1];
@@ -545,12 +563,12 @@ void sqlite3_str_vappendf(
}else{
e2 = exp;
}
if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
bufpt = zExtra
= sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
if( bufpt==0 ){
setStrAccumError(pAccum, SQLITE_NOMEM);
return;
{
i64 szBufNeeded; /* Size of a temporary buffer needed */
szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15;
if( szBufNeeded > etBUFSIZE ){
bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded);
if( bufpt==0 ) return;
}
}
zOut = bufpt;
@@ -774,11 +792,8 @@ void sqlite3_str_vappendf(
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 3;
if( n>etBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){
setStrAccumError(pAccum, SQLITE_NOMEM);
return;
}
bufpt = zExtra = printfTempBuf(pAccum, n);
if( bufpt==0 ) return;
}else{
bufpt = buf;
}