Skip to content

MDEV-40571 insufficient validation of frm data when opening a table - #5477

Open
vuvova wants to merge 1 commit into
10.6from
bb-10.6-serg
Open

MDEV-40571 insufficient validation of frm data when opening a table#5477
vuvova wants to merge 1 commit into
10.6from
bb-10.6-serg

Conversation

@vuvova

@vuvova vuvova commented Jul 31, 2026

Copy link
Copy Markdown
Member

numerous checks that the frm is valid, no OOB reads, values make sense (number of keyparts not less than number of keys, no keys means no keyparts, number of long unique fields is not larger than number of fields, fields values in the record don't overlap and don't go over record ends, and so on). most asserts were changed to if()'s.

numerous checks that the frm is valid, no OOB reads,
values make sense (number of keyparts not less than number of keys,
no keys means no keyparts, number of long unique fields is not larger than
number of fields, fields values in the record don't overlap and don't
go over record ends, and so on). most asserts were changed to if()'s.
@vuvova
vuvova requested a review from Copilot July 31, 2026 16:14
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR strengthens .frm parsing/initialization in TABLE_SHARE::init_from_binary_frm_image() (and related helpers) to better reject malformed/corrupted FRM images and prevent out-of-bounds reads when opening tables.

Changes:

  • Adds multiple structural validation checks while parsing keys, comments, virtual-column screen data, and field layout.
  • Replaces several DBUG_ASSERT()-based assumptions with runtime validation that fails table open on invalid input.
  • Tightens TYPELIB/keyname parsing and introduces new bounds tracking for typelib pointer construction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sql/table.cc
Comment on lines +4970 to 4974
*((*typelib_value_names)++)= ptr;
// Now scan the next value+sep pair
char *vend= (char*) memchr(ptr, sep, end - ptr);
if (!vend)
if (!vend || *typelib_value_names >= names_end)
return true; // Bad format

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope. it's incremented but not dereferenced before the comparison. the comparison verifies that it's valid after it was incremented

Comment thread sql/table.cc
Comment on lines 2270 to 2276
if (!multi_alloc_root(&share->mem_root,
&share->field, (uint)(share->fields+1)*sizeof(Field*),
&share->intervals, (uint)interval_count*sizeof(TYPELIB),
&share->check_constraints, (uint) share->table_check_constraints * sizeof(Virtual_column_info*),
/*
This looks wrong: shouldn't it be (+2+interval_count)
instread of (+3) ?
*/
&interval_array, (uint) (share->fields+interval_parts+ keys+3)*sizeof(char *),
&interval_array, total_typelib_value_count * sizeof(char **),
&typelib_value_lengths, total_typelib_value_count * sizeof(uint *),
&names, (uint) (n_length+int_length),

@vuvova vuvova Jul 31, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my line is exactly the same as the old line below, so must be ok

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've removed the (uint) cast. so should be (uint) total_typelib_value_count * sizeof(char *) and sizeof(char*), not like it makes much difference, is this is the same of the array element.

Comment thread sql/table.cc
Comment on lines 1077 to 1081
if ((strpos[10] & MYSQL57_GENERATED_FIELD))
{
if (vcol_screen_pos + MYSQL57_GCOL_HEADER_SIZE >= vcol_screen_end)
return;
/* Skip virtual (not stored) generated field */

@vuvova vuvova Jul 31, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fine, it's just a quick check for null fields. vcol_screen will be properly parsed later and the error will be returned from there

@vuvova
vuvova requested a review from vaintroub July 31, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants