/ Check-in [179e5d46]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 179e5d46054e5c86f53a79b7a0823d9a383da8391ad1d3c3b22645927a1e052b
User & Date: drh 2019-02-01 20:29:04
Context
2019-02-01
21:08
Slight adjustment to the printf formatter large memory allocation detector so that it does not overestimate the amount of space needed for oversize %d conversions. check-in: 1aee70d6 user: drh tags: trunk
20:29
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. check-in: 179e5d46 user: drh tags: trunk
18:46
Performance improvement in the parsing of options to %-formats in the printf implementation. check-in: 40d8f8ae user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/printf.c.

   151    151     return sqlite3_value_double(p->apArg[p->nUsed++]);
   152    152   }
   153    153   static char *getTextArg(PrintfArguments *p){
   154    154     if( p->nArg<=p->nUsed ) return 0;
   155    155     return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
   156    156   }
   157    157   
          158  +/*
          159  +** Allocate memory for a temporary buffer needed for printf rendering.
          160  +**
          161  +** If the requested size of the temp buffer is larger than the size
          162  +** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error.
          163  +** Do the size check before the memory allocation to prevent rogue
          164  +** SQL from requesting large allocations using the precision or width
          165  +** field of the printf() function.
          166  +*/
          167  +static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
          168  +  char *z;
          169  +  if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){
          170  +    setStrAccumError(pAccum, SQLITE_TOOBIG);
          171  +    return 0;
          172  +  }
          173  +  z = sqlite3DbMallocRaw(pAccum->db, n);
          174  +  if( z==0 ){
          175  +    setStrAccumError(pAccum, SQLITE_NOMEM);
          176  +  }
          177  +  return z;
          178  +}
   158    179   
   159    180   /*
   160    181   ** On machines with a small stack size, you can redefine the
   161    182   ** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
   162    183   */
   163    184   #ifndef SQLITE_PRINT_BUF_SIZE
   164    185   # define SQLITE_PRINT_BUF_SIZE 70
................................................................................
   418    439             precision = width-(prefix!=0);
   419    440           }
   420    441           if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
   421    442             nOut = etBUFSIZE;
   422    443             zOut = buf;
   423    444           }else{
   424    445             u64 n = (u64)precision + 10 + precision/3;
   425         -          zOut = zExtra = sqlite3Malloc( n );
   426         -          if( zOut==0 ){
   427         -            setStrAccumError(pAccum, SQLITE_NOMEM);
   428         -            return;
   429         -          }
          446  +          zOut = zExtra = printfTempBuf(pAccum, n);
          447  +          if( zOut==0 ) return;
   430    448             nOut = (int)n;
   431    449           }
   432    450           bufpt = &zOut[nOut-1];
   433    451           if( xtype==etORDINAL ){
   434    452             static const char zOrd[] = "thstndrd";
   435    453             int x = (int)(longvalue % 10);
   436    454             if( x>=4 || (longvalue/10)%10==1 ){
................................................................................
   541    559             flag_rtz = flag_altform2;
   542    560           }
   543    561           if( xtype==etEXP ){
   544    562             e2 = 0;
   545    563           }else{
   546    564             e2 = exp;
   547    565           }
   548         -        if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
   549         -          bufpt = zExtra 
   550         -              = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
   551         -          if( bufpt==0 ){
   552         -            setStrAccumError(pAccum, SQLITE_NOMEM);
   553         -            return;
          566  +        {
          567  +          i64 szBufNeeded;           /* Size of a temporary buffer needed */
          568  +          szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15;
          569  +          if( szBufNeeded > etBUFSIZE ){
          570  +            bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded);
          571  +            if( bufpt==0 ) return;
   554    572             }
   555    573           }
   556    574           zOut = bufpt;
   557    575           nsd = 16 + flag_altform2*10;
   558    576           flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
   559    577           /* The sign in front of the number */
   560    578           if( prefix ){
................................................................................
   770    788             if( flag_altform2 && (ch&0xc0)==0xc0 ){
   771    789               while( (escarg[i+1]&0xc0)==0x80 ){ i++; }
   772    790             }
   773    791           }
   774    792           needQuote = !isnull && xtype==etSQLESCAPE2;
   775    793           n += i + 3;
   776    794           if( n>etBUFSIZE ){
   777         -          bufpt = zExtra = sqlite3Malloc( n );
   778         -          if( bufpt==0 ){
   779         -            setStrAccumError(pAccum, SQLITE_NOMEM);
   780         -            return;
   781         -          }
          795  +          bufpt = zExtra = printfTempBuf(pAccum, n);
          796  +          if( bufpt==0 ) return;
   782    797           }else{
   783    798             bufpt = buf;
   784    799           }
   785    800           j = 0;
   786    801           if( needQuote ) bufpt[j++] = q;
   787    802           k = i;
   788    803           for(i=0; i<k; i++){