MDEV-15723 Crash in INFORMATION_SCHEMA.INNODB_SYS_TABLES when accessing corrupted record

dict_load_table_low(): When flagging an error, assign *table = NULL.
Failure to do so could cause a crash if an error was flagged when
accessing INFORMATION_SCHEMA.INNODB_SYS_TABLES.
This commit is contained in:
Marko Mäkelä 2018-04-23 16:19:50 +03:00
parent fcaf619400
commit c7bb337248
2 changed files with 10 additions and 1 deletions

View File

@ -1,6 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -2057,10 +2058,12 @@ dict_load_table_low(
ulint flags2; ulint flags2;
if (rec_get_deleted_flag(rec, 0)) { if (rec_get_deleted_flag(rec, 0)) {
*table = NULL;
return("delete-marked record in SYS_TABLES"); return("delete-marked record in SYS_TABLES");
} }
if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_TABLES) { if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_TABLES) {
*table = NULL;
return("wrong number of columns in SYS_TABLES record"); return("wrong number of columns in SYS_TABLES record");
} }
@ -2068,6 +2071,7 @@ dict_load_table_low(
rec, DICT_FLD__SYS_TABLES__NAME, &len); rec, DICT_FLD__SYS_TABLES__NAME, &len);
if (len == 0 || len == UNIV_SQL_NULL) { if (len == 0 || len == UNIV_SQL_NULL) {
err_len: err_len:
*table = NULL;
return("incorrect column length in SYS_TABLES"); return("incorrect column length in SYS_TABLES");
} }
rec_get_nth_field_offs_old( rec_get_nth_field_offs_old(
@ -2147,6 +2151,7 @@ err_len:
"InnoDB: in InnoDB data dictionary" "InnoDB: in InnoDB data dictionary"
" has unknown type %lx.\n", " has unknown type %lx.\n",
(ulong) flags); (ulong) flags);
*table = NULL;
return("incorrect flags in SYS_TABLES"); return("incorrect flags in SYS_TABLES");
} }

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
@ -2059,10 +2059,12 @@ dict_load_table_low(
ulint flags2; ulint flags2;
if (rec_get_deleted_flag(rec, 0)) { if (rec_get_deleted_flag(rec, 0)) {
*table = NULL;
return("delete-marked record in SYS_TABLES"); return("delete-marked record in SYS_TABLES");
} }
if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_TABLES) { if (rec_get_n_fields_old(rec) != DICT_NUM_FIELDS__SYS_TABLES) {
*table = NULL;
return("wrong number of columns in SYS_TABLES record"); return("wrong number of columns in SYS_TABLES record");
} }
@ -2070,6 +2072,7 @@ dict_load_table_low(
rec, DICT_FLD__SYS_TABLES__NAME, &len); rec, DICT_FLD__SYS_TABLES__NAME, &len);
if (len == 0 || len == UNIV_SQL_NULL) { if (len == 0 || len == UNIV_SQL_NULL) {
err_len: err_len:
*table = NULL;
return("incorrect column length in SYS_TABLES"); return("incorrect column length in SYS_TABLES");
} }
rec_get_nth_field_offs_old( rec_get_nth_field_offs_old(
@ -2149,6 +2152,7 @@ err_len:
"InnoDB: in InnoDB data dictionary" "InnoDB: in InnoDB data dictionary"
" has unknown type %lx.\n", " has unknown type %lx.\n",
(ulong) flags); (ulong) flags);
*table = NULL;
return("incorrect flags in SYS_TABLES"); return("incorrect flags in SYS_TABLES");
} }