Bug #107679 May operate uninitialized memory during Parallel_reader::Scan_ctx::copy_row()
Submitted: 28 Jun 2022 8:07 Modified: 29 Jun 2022 13:03
Reporter: zhang yinggang Email Updates:
Status: Verified Impact on me:
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any

[28 Jun 2022 8:07] zhang yinggang
At function Parallel_reader::Scan_ctx::copy_row(), using the following code to copy a physical rec.

  auto rec_len = rec_offs_size(iter->m_offsets);

  auto copy_rec = static_cast<rec_t *>(mem_heap_alloc(iter->m_heap, rec_len));

  memcpy(copy_rec, rec, rec_len);

  iter->m_rec = copy_rec;
 Cause rec points to the begining of data in a physical record, rec_len is the total size of a physical which include data size and extra size. Then the memcpy will operate the uninitialized memory. And this function can't work as expected

How to repeat:
This code can be execute by runing CHECK TABLE statement. Cause the following operation only use the data part of copy_rec, it can work well so far.

Suggested fix:
This bug can fix like:

  auto extra_len = rec_offs_extra_size(iter->m_offsets);
  auto data_len = rec_offs_data_size(iter->m_offsets);
  auto rec_len = data_len + extra_len;

  auto copy_rec = static_cast<rec_t *>(mem_heap_alloc(iter->m_heap, rec_len));

  memcpy(copy_rec, rec - extra_len, rec_len);

  iter->m_rec = copy_rec + extra_len;


Calling rec_copy() also can solve this bugs.
[28 Jun 2022 14:51] MySQL Verification Team
Hi Mr. yinggang,

Thank you for your bug report.

However, we do not think that it is a bug.

The pointers are correct and the sizes are correct. Yes, it is true that more is gathered from the record, but it includes both raw data and meta data.

Hence, we do not see the need to change the code.

If you can make a test case that would prove otherwise, we will be happy to reconsider.
[29 Jun 2022 3:19] Qingda Hu
I think Mr. yinggang are right. 

    memcpy(copy_rec, rec, rec_len);

In the above codes, either the rec pointer or the rec_len is wrong. 

If u want to copy both raw data and meta extra data, u need to set the pointer to rec - extra_len. And if u only need to copy raw data, u need to set the rec_len equal to data_len.
[29 Jun 2022 12:19] MySQL Verification Team
Hi Mr. yinggang,

We have ran some additional analysis and concluded that our hack in that code is not clear enough.

Hence, this is now a verified bug.
[29 Jun 2022 13:03] MySQL Verification Team
Correct status.