From 22e99fcb34712e710c6fe086d44e3643479f9e76 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Fri, 29 Jun 2018 12:09:18 +0530 Subject: Bug#27799513: POTENTIAL DOUBLE FREE OR CORRUPTION OF HEAP INFO (HP_INFO) Description:- Server crashes due to memory overflow. Analysis:- Bytes for storing key length is wrongly set for HEAP tables. Fix:- Bytes used to store the key length is properly set inside "heap_create()". --- storage/heap/hp_create.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'storage') diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index 93928cd479e..d32a69dd630 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. 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 @@ -92,7 +92,14 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, /* fall_through */ case HA_KEYTYPE_VARTEXT1: keyinfo->flag|= HA_VAR_LENGTH_KEY; - length+= 2; + /* + For BTREE algorithm, key length, greater than or equal + to 255, is packed on 3 bytes. + */ + if (keyinfo->algorithm == HA_KEY_ALG_BTREE) + length+= size_to_store_key_length(keyinfo->seg[j].length); + else + length+= 2; /* Save number of bytes used to store length */ keyinfo->seg[j].bit_start= 1; break; @@ -101,7 +108,14 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, /* fall_through */ case HA_KEYTYPE_VARTEXT2: keyinfo->flag|= HA_VAR_LENGTH_KEY; - length+= 2; + /* + For BTREE algorithm, key length, greater than or equal + to 255, is packed on 3 bytes. + */ + if (keyinfo->algorithm == HA_KEY_ALG_BTREE) + length+= size_to_store_key_length(keyinfo->seg[j].length); + else + length+= 2; /* Save number of bytes used to store length */ keyinfo->seg[j].bit_start= 2; /* -- cgit v1.2.1 From 3d65d0db1611f3aea3e1bcde22949351f3b89661 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 4 Sep 2018 23:19:07 +0200 Subject: MDEV-9137 MariaDB Crash on Query Using Aria Engine Two bugs in Aria, related to 2-level fulltext indexes: * REPAIR calculated the key number incorrectly * CHECK copied the key into last_key too early and checking the second-level btree was overwriting it --- storage/maria/ma_check.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'storage') diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 198df72a1d6..d6379dc4d91 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -891,8 +891,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo, if (level > param->max_level) param->max_level=level; - if (_ma_get_keynr(share, anc_page->buff) != - (uint) (keyinfo - share->keyinfo)) + if (_ma_get_keynr(share, anc_page->buff) != keyinfo->key_nr) _ma_check_print_error(param, "Page at %s is not marked for index %u", llstr(anc_page->pos, llbuff), (uint) (keyinfo - share->keyinfo)); @@ -916,7 +915,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo, info->last_key.keyinfo= tmp_key.keyinfo= keyinfo; info->lastinx= ~0; /* Safety */ tmp_key.data= tmp_key_buff; - for ( ;; ) + for ( ;; _ma_copy_key(&info->last_key, &tmp_key)) { if (nod_flag) { @@ -998,7 +997,6 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo, tmp_key.data); } } - _ma_copy_key(&info->last_key, &tmp_key); (*key_checksum)+= maria_byte_checksum(tmp_key.data, tmp_key.data_length); record= _ma_row_pos_from_key(&tmp_key); @@ -5728,8 +5726,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param, a_length= share->keypage_header + nod_flag; key_block->end_pos= anc_buff + share->keypage_header; bzero(anc_buff, share->keypage_header); - _ma_store_keynr(share, anc_buff, (uint) (sort_param->keyinfo - - share->keyinfo)); + _ma_store_keynr(share, anc_buff, sort_param->keyinfo->key_nr); lastkey=0; /* No previous key in block */ } else -- cgit v1.2.1 From 7438667fa96433605078ada7874fc17eac925d9f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 5 Sep 2018 00:59:04 +0200 Subject: MDEV-9137 MariaDB Crash on Query Using Aria Engine update the code to match semantics of `key` - it's not a (char*) pointer to the buffer as in MyISAM. --- storage/maria/ma_write.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'storage') diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index a9022417986..842f3a0aa8d 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -665,13 +665,18 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key, else { /* popular word. two-level tree. going down */ - my_off_t root=dup_key_pos; - keyinfo= &share->ft2_keyinfo; - get_key_full_length_rdonly(off, key); - key+=off; + my_off_t root= dup_key_pos; + MARIA_KEY subkey; + get_key_full_length_rdonly(off, key->data); + subkey.keyinfo= keyinfo= &share->ft2_keyinfo; + subkey.data= key->data + off; + subkey.data_length= key->data_length - off; + subkey.ref_length= key->ref_length; + subkey.flag= key->flag; + /* we'll modify key entry 'in vivo' */ keypos-= keyinfo->keylength + page.node; - error= _ma_ck_real_write_btree(info, key, &root, comp_flag); + error= _ma_ck_real_write_btree(info, &subkey, &root, comp_flag); _ma_dpointer(share, keypos+HA_FT_WLEN, root); subkeys--; /* should there be underflow protection ? */ DBUG_ASSERT(subkeys < 0); -- cgit v1.2.1 From fb324e3f8f7e81f60f19aa0840550acdcbbc429f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 5 Sep 2018 01:34:25 +0200 Subject: MDEV-9137 MariaDB Crash on Query Using Aria Engine fix for 2-level ft indexes and boolean search in Aria --- storage/maria/ma_ft_boolean_search.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'storage') diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c index 83ae08553ef..d4578ad6bd7 100644 --- a/storage/maria/ma_ft_boolean_search.c +++ b/storage/maria/ma_ft_boolean_search.c @@ -457,7 +457,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) */ ftbw->off=off; ftbw->key_root= info->cur_row.lastpos; - ftbw->keyinfo=& info->s->ft2_keyinfo; + ftbw->keyinfo= info->last_key.keyinfo= & info->s->ft2_keyinfo; r= _ma_search_first(info, ftbw->keyinfo, ftbw->key_root); DBUG_ASSERT(r==0); /* found something */ memcpy(lastkey_buf+off, info->last_key.data, -- cgit v1.2.1 From 5bc30247c4b79021f99303cd65dfa75d4504a773 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 24 Oct 2018 10:30:31 +0200 Subject: 5.5.61-38.13 --- storage/xtradb/.clang-format | 111 ++++++++++++++++++++++++++++++++++++ storage/xtradb/CMakeLists.txt | 5 ++ storage/xtradb/fsp/fsp0fsp.c | 37 ------------ storage/xtradb/handler/ha_innodb.cc | 12 ++-- storage/xtradb/handler/ha_innodb.h | 2 +- storage/xtradb/include/data0type.ic | 2 + storage/xtradb/include/univ.i | 2 +- storage/xtradb/log/log0online.c | 4 +- storage/xtradb/os/os0sync.c | 18 ------ storage/xtradb/row/row0sel.c | 1 + storage/xtradb/srv/srv0srv.c | 2 + storage/xtradb/sync/sync0sync.c | 4 +- 12 files changed, 135 insertions(+), 65 deletions(-) create mode 100644 storage/xtradb/.clang-format (limited to 'storage') diff --git a/storage/xtradb/.clang-format b/storage/xtradb/.clang-format new file mode 100644 index 00000000000..d757d0a5a05 --- /dev/null +++ b/storage/xtradb/.clang-format @@ -0,0 +1,111 @@ +# generated with: +# clang-format-5.0 -style=Google --dump-config + +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +SortUsingDeclarations: true +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 + + +# changes for MySQL 5.x (InnoDB) +AlignConsecutiveDeclarations: true +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: All +ColumnLimit: 78 +DerivePointerAlignment: false +IndentWidth: 8 +MaxEmptyLinesToKeep: 2 +PointerAlignment: Right +ReflowComments: false +SortIncludes: false +SpaceAfterCStyleCast: true +UseTab: Always diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index b97473849ef..91033e60dc6 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -308,3 +308,8 @@ MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE DEFAULT MODULE_OUTPUT_NAME ha_innodb LINK_LIBRARIES ${ZLIB_LIBRARY}) + +IF(WITH_INNOBASE_STORAGE_ENGINE) + # Remove -DMYSQL_SERVER, it breaks embedded build + SET_TARGET_PROPERTIES(innobase PROPERTIES COMPILE_DEFINITIONS "") +ENDIF() diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c index 8927e7c5841..9abbd8172bc 100644 --- a/storage/xtradb/fsp/fsp0fsp.c +++ b/storage/xtradb/fsp/fsp0fsp.c @@ -431,43 +431,6 @@ xdes_find_bit( return(ULINT_UNDEFINED); } -/**********************************************************************//** -Looks for a descriptor bit having the desired value. Scans the extent in -a direction opposite to xdes_find_bit. -@return bit index of the bit, ULINT_UNDEFINED if not found */ -UNIV_INLINE -ulint -xdes_find_bit_downward( -/*===================*/ - xdes_t* descr, /*!< in: descriptor */ - ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */ - ibool val, /*!< in: desired bit value */ - ulint hint, /*!< in: hint of which bit position would be desirable */ - mtr_t* mtr) /*!< in: mtr */ -{ - ulint i; - - ut_ad(descr && mtr); - ut_ad(val <= TRUE); - ut_ad(hint < FSP_EXTENT_SIZE); - ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); - for (i = hint + 1; i > 0; i--) { - if (val == xdes_get_bit(descr, bit, i - 1, mtr)) { - - return(i - 1); - } - } - - for (i = FSP_EXTENT_SIZE - 1; i > hint; i--) { - if (val == xdes_get_bit(descr, bit, i, mtr)) { - - return(i); - } - } - - return(ULINT_UNDEFINED); -} - /**********************************************************************//** Returns the number of used pages in a descriptor. @return number of pages used */ diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3850b4a12e8..cc4b782cb18 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -1938,6 +1938,7 @@ trx_is_registered_for_2pc( /*********************************************************************//** Note that a transaction owns the prepare_commit_mutex. */ +#ifndef EXTENDED_FOR_COMMIT_ORDERED static inline void trx_owns_prepare_commit_mutex_set( @@ -1947,6 +1948,7 @@ trx_owns_prepare_commit_mutex_set( ut_a(trx_is_registered_for_2pc(trx)); trx->owns_prepare_mutex = 1; } +#endif // EXTENDED_FOR_COMMIT_ORDERED /*********************************************************************//** Note that a transaction has been registered with MySQL 2PC coordinator. */ @@ -5830,7 +5832,7 @@ build_template( if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) { /* Decide which columns we should fetch and which we can skip. */ - register const ibool index_contains_field = + const ibool index_contains_field = dict_index_contains_col_or_prefix(index, i); if (!index_contains_field && prebuilt->read_just_key) { @@ -6199,6 +6201,8 @@ no_commit: innodb_srv_conc_enter_innodb(prebuilt->trx); error = row_insert_for_mysql((byte*) record, prebuilt); + DEBUG_SYNC(user_thd, "ib_after_row_insert"); + #ifdef EXTENDED_FOR_USERSTAT if (UNIV_LIKELY(error == DB_SUCCESS && !trx->fake_changes)) { @@ -7648,8 +7652,6 @@ create_table_def( } } - ut_a(field->type() < 256); /* we assume in dtype_form_prtype() - that this fits in one byte */ col_len = field->pack_length(); /* The MySQL pack length contains 1 or 2 bytes length field @@ -10404,8 +10406,10 @@ ha_innobase::start_stmt( case SQLCOM_INSERT: case SQLCOM_UPDATE: case SQLCOM_DELETE: + case SQLCOM_REPLACE: init_table_handle_for_HANDLER(); prebuilt->select_lock_type = LOCK_X; + prebuilt->stored_select_lock_type = LOCK_X; error = row_lock_table_for_mysql(prebuilt, NULL, 1); if (error != DB_SUCCESS) { diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 4f21dcff7e8..aaf897afdf8 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -183,7 +183,7 @@ class ha_innobase: public handler ha_rows estimate_rows_upper_bound(); void update_create_info(HA_CREATE_INFO* create_info); - int create(const char *name, register TABLE *form, + int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); int truncate(); int delete_table(const char *name); diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic index a04fa632886..48ab18ef6b6 100644 --- a/storage/xtradb/include/data0type.ic +++ b/storage/xtradb/include/data0type.ic @@ -446,6 +446,7 @@ dtype_get_fixed_size_low( return(0); } #endif /* UNIV_DEBUG */ + // fallthrough case DATA_CHAR: case DATA_FIXBINARY: case DATA_INT: @@ -524,6 +525,7 @@ dtype_get_min_size_low( return(0); } #endif /* UNIV_DEBUG */ + // fallthrough case DATA_CHAR: case DATA_FIXBINARY: case DATA_INT: diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 64a2bfa70fe..b6861d62394 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -64,7 +64,7 @@ component, i.e. we show M.N.P as M.N */ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 38.11 +#define PERCONA_INNODB_VERSION 38.13 #endif #define INNODB_VERSION_STR MYSQL_SERVER_VERSION diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c index 0354ef29ea8..c6e8c7c5198 100644 --- a/storage/xtradb/log/log0online.c +++ b/storage/xtradb/log/log0online.c @@ -1561,10 +1561,10 @@ log_online_open_bitmap_file_read_only( if (srv_data_home_len && srv_data_home[srv_data_home_len-1] != SRV_PATH_SEPARATOR) { - ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%c%s", + ut_snprintf(bitmap_file->name, sizeof(bitmap_file->name), "%s%c%s", srv_data_home, SRV_PATH_SEPARATOR, name); } else { - ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", + ut_snprintf(bitmap_file->name, sizeof(bitmap_file->name), "%s%s", srv_data_home, name); } bitmap_file->file diff --git a/storage/xtradb/os/os0sync.c b/storage/xtradb/os/os0sync.c index 3a182692da3..642451dcc2c 100644 --- a/storage/xtradb/os/os0sync.c +++ b/storage/xtradb/os/os0sync.c @@ -226,24 +226,6 @@ os_cond_broadcast( #endif } -/*********************************************************//** -Wakes one thread waiting for condition variable */ -UNIV_INLINE -void -os_cond_signal( -/*==========*/ - os_cond_t* cond) /*!< in: condition variable. */ -{ - ut_a(cond); - -#ifdef __WIN__ - ut_a(wake_condition_variable != NULL); - wake_condition_variable(cond); -#else - ut_a(pthread_cond_signal(cond) == 0); -#endif -} - /*********************************************************//** Destroys condition variable */ UNIV_INLINE diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index 140cfc61383..d021ff1445f 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -4298,6 +4298,7 @@ no_gap_lock: prebuilt->new_rec_locks = 1; } err = DB_SUCCESS; + break; case DB_SUCCESS: break; case DB_LOCK_WAIT: diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c index 3770a8804dd..b55e9fc44cd 100644 --- a/storage/xtradb/srv/srv0srv.c +++ b/storage/xtradb/srv/srv0srv.c @@ -1402,6 +1402,8 @@ retry: os_fast_mutex_unlock(&srv_conc_mutex); + DEBUG_SYNC_C("user_thread_waiting"); + trx->op_info = "sleeping before joining InnoDB queue"; /* Peter Zaitsev suggested that we take the sleep away diff --git a/storage/xtradb/sync/sync0sync.c b/storage/xtradb/sync/sync0sync.c index 7654fade6e8..27138629dbc 100644 --- a/storage/xtradb/sync/sync0sync.c +++ b/storage/xtradb/sync/sync0sync.c @@ -315,9 +315,9 @@ mutex_create_func( /* NOTE! The very first mutexes are not put to the mutex list */ - if ((mutex == &mutex_list_mutex) + if (mutex == &mutex_list_mutex #ifdef UNIV_SYNC_DEBUG - || (mutex == &sync_thread_mutex) + || mutex == &sync_thread_mutex #endif /* UNIV_SYNC_DEBUG */ ) { -- cgit v1.2.1