mirror of
https://github.com/MariaDB/server.git
synced 2026-05-14 19:07:15 +02:00
MDEV-24620 ASAN heap-buffer-overflow in btr_pcur_restore_position()
Between btr_pcur_store_position() and btr_pcur_restore_position() it is possible that purge empties a table and enlarges index->n_core_fields and index->n_core_null_bytes. Therefore, we must cache index->n_core_fields in btr_pcur_t::old_n_core_fields so that btr_pcur_t::old_rec can be parsed correctly. Unfortunately, this is a huge change, because we will replace "bool leaf" parameters with "ulint n_core" (passing index->n_core_fields, or 0 for non-leaf pages). For special cases where we know that index->is_instant() cannot hold, we may also pass index->n_fields.
This commit is contained in:
parent
6e6318b29b
commit
b8c8692fd9
42 changed files with 614 additions and 421 deletions
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||
|
||||
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
|
||||
|
|
@ -497,8 +497,10 @@ struct btr_pcur_t{
|
|||
/** if cursor position is stored, contains an initial segment of the
|
||||
latest record cursor was positioned either on, before or after */
|
||||
rec_t* old_rec;
|
||||
/** btr_cur.index->n_core_fields when old_rec was copied */
|
||||
uint16 old_n_core_fields;
|
||||
/** number of fields in old_rec */
|
||||
ulint old_n_fields;
|
||||
uint16 old_n_fields;
|
||||
/** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on
|
||||
whether cursor was on, before, or after the old_rec record */
|
||||
enum btr_pcur_pos_t rel_pos;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2021, MariaDB Corporation.
|
||||
|
||||
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
|
||||
|
|
@ -1348,21 +1348,6 @@ dict_index_build_node_ptr(
|
|||
ulint level) /*!< in: level of rec in tree:
|
||||
0 means leaf level */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
/**********************************************************************//**
|
||||
Copies an initial segment of a physical record, long enough to specify an
|
||||
index entry uniquely.
|
||||
@return pointer to the prefix record */
|
||||
rec_t*
|
||||
dict_index_copy_rec_order_prefix(
|
||||
/*=============================*/
|
||||
const dict_index_t* index, /*!< in: index */
|
||||
const rec_t* rec, /*!< in: record for which to
|
||||
copy prefix */
|
||||
ulint* n_fields,/*!< out: number of fields copied */
|
||||
byte** buf, /*!< in/out: memory buffer for the
|
||||
copied prefix, or NULL */
|
||||
ulint* buf_size)/*!< in/out: buffer size */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
/** Convert a physical record into a search tuple.
|
||||
@param[in] rec index record (not necessarily in an index page)
|
||||
@param[in] index index
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2021, MariaDB Corporation.
|
||||
|
||||
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
|
||||
|
|
@ -1070,6 +1070,15 @@ struct dict_index_t{
|
|||
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
|
||||
}
|
||||
|
||||
/** @return whether this is a generated clustered index */
|
||||
bool is_gen_clust() const { return type == DICT_CLUSTERED; }
|
||||
|
||||
/** @return whether this is a clustered index */
|
||||
bool is_clust() const { return type & DICT_CLUSTERED; }
|
||||
|
||||
/** @return whether this is a unique index */
|
||||
bool is_unique() const { return type & DICT_UNIQUE; }
|
||||
|
||||
/** @return whether this is a spatial index */
|
||||
bool is_spatial() const { return UNIV_UNLIKELY(type & DICT_SPATIAL); }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||
|
||||
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
|
||||
|
|
@ -57,7 +57,8 @@ rtr_page_cal_mbr(
|
|||
page = buf_block_get_frame(block);
|
||||
|
||||
rec = page_rec_get_next(page_get_infimum_rec(page));
|
||||
offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page),
|
||||
offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page)
|
||||
? index->n_fields : 0,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2015, 2021, MariaDB Corporation.
|
||||
|
||||
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
|
||||
|
|
@ -278,7 +278,8 @@ page_cur_tuple_insert(
|
|||
index, tuple, n_ext);
|
||||
|
||||
*offsets = rec_get_offsets(rec, index, *offsets,
|
||||
page_is_leaf(cursor->block->frame),
|
||||
page_is_leaf(cursor->block->frame)
|
||||
? index->n_core_fields : 0,
|
||||
ULINT_UNDEFINED, heap);
|
||||
|
||||
if (buf_block_get_page_zip(cursor->block)) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||
|
||||
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
|
||||
|
|
@ -554,7 +554,7 @@ rec_get_n_extern_new(
|
|||
@param[in] index the index that the record belongs to
|
||||
@param[in,out] offsets array comprising offsets[0] allocated elements,
|
||||
or an array from rec_get_offsets(), or NULL
|
||||
@param[in] leaf whether this is a leaf-page record
|
||||
@param[in] n_core 0, or index->n_core_fields for leaf page
|
||||
@param[in] n_fields maximum number of offsets to compute
|
||||
(ULINT_UNDEFINED to compute all offsets)
|
||||
@param[in,out] heap memory heap
|
||||
|
|
@ -564,7 +564,7 @@ rec_get_offsets_func(
|
|||
const rec_t* rec,
|
||||
const dict_index_t* index,
|
||||
rec_offs* offsets,
|
||||
bool leaf,
|
||||
ulint n_core,
|
||||
ulint n_fields,
|
||||
#ifdef UNIV_DEBUG
|
||||
const char* file, /*!< in: file name where called */
|
||||
|
|
@ -1121,7 +1121,9 @@ rec_get_converted_size(
|
|||
The fields are copied into the memory heap.
|
||||
@param[out] tuple data tuple
|
||||
@param[in] rec index record, or a copy thereof
|
||||
@param[in] is_leaf whether rec is a leaf page record
|
||||
@param[in] index index of rec
|
||||
@param[in] n_core index->n_core_fields at the time rec was
|
||||
copied, or 0 if non-leaf page record
|
||||
@param[in] n_fields number of fields to copy
|
||||
@param[in,out] heap memory heap */
|
||||
void
|
||||
|
|
@ -1129,7 +1131,7 @@ rec_copy_prefix_to_dtuple(
|
|||
dtuple_t* tuple,
|
||||
const rec_t* rec,
|
||||
const dict_index_t* index,
|
||||
bool is_leaf,
|
||||
ulint n_core,
|
||||
ulint n_fields,
|
||||
mem_heap_t* heap)
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue