/ Check-in [378afa16]
Login

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

Overview
Comment:Avoid an out-of-bounds read on a recovery attempt using a carefully crafted database and rollback journal with mismatched page sizes. The test case for this is in TH3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 378afa16381a222aafa6009dbbbc92473a69683537f1c265694678b0595a42c8
User & Date: drh 2017-09-14 02:36:27
References
2017-09-18
09:40
The out-of-bounds read on recovery fix of check-in [378afa16381a222a] caused problems for some corner-case error conditions. This alternative fix appears to work better. check-in: 74f399d8 user: drh tags: trunk
Context
2017-09-14
20:41
Avoid an out-of-bounds read that can be caused by a specially constructed journal file. check-in: cf5bf42c user: dan tags: trunk
02:36
Avoid an out-of-bounds read on a recovery attempt using a carefully crafted database and rollback journal with mismatched page sizes. The test case for this is in TH3. check-in: 378afa16 user: drh tags: trunk
2017-09-13
20:20
Test case update due to PRAGMA integrity_check enhancements in [8525c30c]. No changes to code. check-in: 43c6023b user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852

2853
2854
2855
2856
2857
2858
2859
....
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
  pPager->journalOff = 0;
  needPagerReset = isHot;

  /* This loop terminates either when a readJournalHdr() or 
  ** pager_playback_one_page() call returns SQLITE_DONE or an IO error 
  ** occurs. 
  */
  while( 1 ){
    /* Read the next journal header from the journal file.  If there are
    ** not enough bytes left in the journal file for a complete header, or
    ** it is corrupted, then a process must have failed while writing it.
    ** This indicates nothing more needs to be rolled back.
    */

    rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
    if( rc!=SQLITE_OK ){ 
      if( rc==SQLITE_DONE ){
        rc = SQLITE_OK;
      }
      goto end_playback;
    }
................................................................................
          ** so that no further harm will be done.  Perhaps the next
          ** process to come along will be able to rollback the database.
          */
          goto end_playback;
        }
      }
    }
  }
  /*NOTREACHED*/
  assert( 0 );

end_playback:
  /* Following a rollback, the database file should be back in its original
  ** state prior to the start of the transaction, so invoke the
  ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
  ** assertion that the transaction counter was modified.
  */







|





>







 







|
|
<







2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
....
2928
2929
2930
2931
2932
2933
2934
2935
2936

2937
2938
2939
2940
2941
2942
2943
  pPager->journalOff = 0;
  needPagerReset = isHot;

  /* This loop terminates either when a readJournalHdr() or 
  ** pager_playback_one_page() call returns SQLITE_DONE or an IO error 
  ** occurs. 
  */
  do{
    /* Read the next journal header from the journal file.  If there are
    ** not enough bytes left in the journal file for a complete header, or
    ** it is corrupted, then a process must have failed while writing it.
    ** This indicates nothing more needs to be rolled back.
    */
    u32 savedPageSize = pPager->pageSize;
    rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
    if( rc!=SQLITE_OK ){ 
      if( rc==SQLITE_DONE ){
        rc = SQLITE_OK;
      }
      goto end_playback;
    }
................................................................................
          ** so that no further harm will be done.  Perhaps the next
          ** process to come along will be able to rollback the database.
          */
          goto end_playback;
        }
      }
    }
    rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1);
  }while( rc==SQLITE_OK );


end_playback:
  /* Following a rollback, the database file should be back in its original
  ** state prior to the start of the transaction, so invoke the
  ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
  ** assertion that the transaction counter was modified.
  */