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:
47
src/printf.c
47
src/printf.c
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user