Bug #41227 Falcon: potential corruption of RecordLocatorPage on recovery
Submitted: 4 Dec 2008 14:00 Modified: 15 May 2009 13:04
Reporter: Sergey Vojtovich Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Falcon storage engine Severity:S3 (Non-critical)
Version:6.0.9 OS:Any
Assigned to: Vladislav Vaintroub CPU Architecture:Any
Tags: F_RECOVERY
Triage: Triaged: D1 (Critical)

[4 Dec 2008 14:00] Sergey Vojtovich
Description:
There are two Falcon functions that may be called on recovery: Section::redoBlobUpdate() and Section::redoBlobDelete().

Both of them call RecordLocatorPage::setIndexSlot() with last parameter (spaceAvailable) set to dbb->pageSize:
page->setIndexSlot(locatorLine, dataPage, dataLine, dbb->pageSize);
and
page->setIndexSlot(locatorLine, 0, 0, dbb->pageSize);

This is likely incorrect, because there should be at least DataPage structure on the page. As a result RecordLocatorPage may store incorrect information. Also with falcon_page size set to 32k we'll get short integer overrun.

When fixing this, please add an assert to the RecordLocatorPage::setIndexSlot():
- ASSERT(availableSpace >= 0);
+ ASSERT(availableSpace >= 0 && availableSpace < 0x8000);
or
+ ASSERT(availableSpace >= 0 && availableSpace < dbb->pageSize);
or even better
+ ASSERT(availableSpace >= 0 && availableSpace < dbb->pageSize - OFFSET (DataPage*, lineIndex)

Found while fixing BUG#39456.

How to repeat:
To be verified by code analysis at the moment.
[29 Jan 2009 15:26] Kevin Lewis
Vlad, This bug is not verified.  Can you evaluate this request for verification.  And fix it if necessary?
[29 Jan 2009 16:50] Vladislav Vaintroub
verified by falcon_pagesize_32K in pushbuild2.
recovery crashes with "corrupt record locator page"
[30 Jan 2009 1:29] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/64580

2988 Vladislav Vaintroub	2009-01-30
      Bug#41227  Falcon: potential corruption of RecordLocatorPage 
      on recovery
      
      Problem: If falcon pager size is set to 32K, recovery 
      involving blob updates will crash in assertion. 
      
      Section::redoBlobUpdate and Section::redoBlobDelete will
      try to set available space to the page size (32K)in record locator page
      However, 32K=32768  becomes negative (-32768) when converted to short.
      RecordLocatorPage::linkSpaceSlot() checks for positive value for 
      "space available" and asserts.
      
      Fix is to set spaceAvailable to more realistic value 
      (page size - page header overhead) that is guaranteed not to overflow 
      and not to change sign of a short even for 32 K pages.
[30 Jan 2009 6:25] Kevin Lewis
Patch looks good.  Guessing that the impact is substantial.
[13 Feb 2009 7:25] Bugs System
Pushed into 6.0.10-alpha (revid:alik@sun.com-20090211182317-uagkyj01fk30p1f8) (version source revid:vvaintroub@mysql.com-20090130012853-wlrtwm7oaqpz9qcr) (merge vers: 6.0.10-alpha) (pib:6)
[15 May 2009 13:04] MC Brown
An entry has been added to the 6.0.10 changelog: 

Recovery of Falcon tables after a crash if falcon_page_size had been set to 32K and BLOB columns were used in the Falcon tables