PS 5.6 corrupt_table_action needs fixes

Bug #1154950 reported by Stewart Smith
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Percona Server moved to https://jira.percona.com/projects/PS
Status tracked in 5.7
5.1
Won't Fix
Medium
Unassigned
5.5
Triaged
Medium
Unassigned
5.6
Triaged
Medium
Unassigned
5.7
Triaged
Medium
Unassigned

Bug Description

George reviewed at https://code.launchpad.net/~stewart/percona-server/5.6-corrupt-table-action/+merge/140341/comments/306227

reproduced below:

There is a possible bad memory read now in btr0cur.cc:btr_get_height
  root_block = btr_root_block_get(index, RW_S_LATCH, mtr);
  height = btr_page_get_level(buf_block_get_frame(root_block), mtr);

  btr_root_block_get can now return NULL, assigning the NULL to the local 'root_block'.

  The call to buf_block_get_frame(root_block) will return NULL as well, passing that into btr_page_get_level.

  In btr_page_get_level_low where page is now NULL:
    mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL); which does no validation for a NULL pointer.

  So either mach_read_from_2 will segfault or btr_page_get_level_low will return a completely bogus value and allow execution to continue, returning a bad height from btr_get_height.

If UNIV_BTR_PRINT is defined, there are also similar issues in btr_print_index and btr_print_recursive

There is a similar issue in btr0cur.cc:btr_validate_level where the variables block, page and seg are being used without testing for NULL and passed into btr_page_get_level_low

In all these cases, the return value of btr_root_block_get should probably be tested in conjunction with srv_pass_corrupt_table.

There is also a merge conflict in fsp0fsp.cc:3078.

btr0btr.cc:850 in btr_root_adjust_on_import should probably have a test on (srv_pass_corrupt_table && !block) and return DB_CORRUPTION, this _may_ already be taken care of as a result of some of the subsequent calls.

btr_print_recursive calls btr_print_recursive at btr0btr.cc:4033 directly passing the result of btr_node_ptr_get_child which may return NULL...

btr_validate_level at btr0btr.cc:4435 calls btr_node_ptr_get_child which now may return NULL and assigns it to local variable block, which is then used to get page, which is then used to obtain the page level through btr_page_get_level encountering the same issue described above. Block should be tested here and the loop and function terminated.

All of these call btr_block_get and never check the result for (srv_pass_corrupt_table && !result) before proceeding to use the result:
  btr_attach_half_pages at btr0btr.cc:2678 & 2692
  btr_level_list_remove_func at btr0btr.cc:3172 & 3189
  btr_compress at btr0btr.cc:3515 & 3524
  btr_discard_page at btr0btr.cc:3873 & 3881
  btr_validate_level at btr0btr.cc:4499
  btr_validate_level at btr0btr.cc:4752
  row_merge_read_clustered_index at row0merge.cc:1410

As a result of now possibly returning NULL from fut_get_ptr at fut0fut.ic:54, these may inadvertantly use a NULL pointer without (srv_pass_corrupt_table && !result):
  fsp_alloc_free_page at fsp0fsp.cc:1417 when calling xdes_find_bit with the result of xdes_lst_get_descriptor->fut_get_ptr
  fseg_alloc_free_page_low at fsp0fsp.cc:2513 when calling xdes_get_offset with the result of xdes_lst_get_descriptor->fut_get_ptr
  fseg_validate_low at fsp0fsp.cc:3590, 3616 & 3639 when calling flst_get_next_addr with the result of xdes_lst_get_descriptor->fut_get_ptr
  fsp_validate at fsp0fsp.cc:3840, 3866 & 3891 when calling flst_get_next_addr with the result of xdes_lst_get_descriptor->fut_get_ptr
  fsp_validate at fsp0fsp.cc:3918 & 3963 when calling fsp_seg_inode_page_get_nth_inode and fseg_validate_low with the result of fut_get_ptr
  fsp_print at fsp0fsp.cc:4098 & 4135 when calling fsp_seg_inode_page_get_nth_inode and mach_read_from_8 with the result of fut_get_ptr
  flst_add_last at fut0lst.cc:107 when calling flst_insert_after with the result of fut_get_ptr
  flst_add_first at fut0lst.cc:150 when calling flst_insert_before with the result of fut_get_ptr
  flst_insert_after at fut0lst.cc:198 when calling flst_write_addr with the result of fut_get_ptr
  flst_insert_before at fut0lst.cc:252 when calling flst_write_addr with the result of fut_get_ptr
  flst_remove at fut0lst.cc:309 & 328 when calling flst_write_addr with the result of fut_get_ptr
  flst_cut_end at fut0lst.cc:383 when calling flst_write_addr with the result of fut_get_ptr
  flst_validate at fut0lst.cc:480 when calling flst_get_next_addr with the result of fut_get_ptr
  flst_validate at fut0lst.cc:495 when calling flst_get_prev_addr with the result of fut_get_ptr

tags: added: 56qual
Revision history for this message
Roel Van de Paar (roel11) wrote :

Not often used feature, so no 56qual as per Laurynas

tags: removed: 56qual
tags: added: xtradb
tags: added: corrupt-table-action
Revision history for this message
Shahriyar Rzayev (rzayev-sehriyar) wrote :

Percona now uses JIRA for bug reports so this bug report is migrated to: https://jira.percona.com/browse/PS-1337

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.