summaryrefslogtreecommitdiff
path: root/sql/filesort.cc
diff options
context:
space:
mode:
authorVarun Gupta <varun.gupta@mariadb.com>2020-10-30 14:56:57 +0530
committerMarko Mäkelä <marko.makela@mariadb.com>2020-10-30 12:22:01 +0200
commit5a0c34e4c2fd951119efb432eedcaa65a1d36606 (patch)
tree5e6e21e19580aa9ac77c62b9a6409c6eca3c7d29 /sql/filesort.cc
parent5482d62760bcbdcf44f1340fb5846c3942419dc5 (diff)
downloadmariadb-git-5a0c34e4c2fd951119efb432eedcaa65a1d36606.tar.gz
MDEV-24033: SIGSEGV in __memcmp_avx2_movbe from queue_insert | SIGSEGV in __memcmp_avx2_movbe from native_compare
The issue here was the system variable max_sort_length was being applied to decimals and it was truncating the value for decimals to the number of bytes set by max_sort_length. This was leading to a buffer overflow as the values were written to the buffer without truncation and then we moved the offset to the number of bytes(set by max_sort_length), that are needed for comparison. The fix is to not apply max_sort_length for fixed size types like INT, DECIMALS and only apply max_sort_length for CHAR, VARCHARS, TEXT and BLOBS.
Diffstat (limited to 'sql/filesort.cc')
-rw-r--r--sql/filesort.cc14
1 files changed, 13 insertions, 1 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc
index d76c39c3bd4..96f9aa874da 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1971,7 +1971,14 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
if (sortorder->field)
{
CHARSET_INFO *cs= sortorder->field->sort_charset();
+ sortorder->type= sortorder->field->is_packable() ?
+ SORT_FIELD_ATTR::VARIABLE_SIZE :
+ SORT_FIELD_ATTR::FIXED_SIZE;
+
sortorder->length= sortorder->field->sort_length();
+ if (sortorder->is_variable_sized())
+ set_if_smaller(sortorder->length, thd->variables.max_sort_length);
+
if (use_strnxfrm((cs=sortorder->field->sort_charset())))
{
*multi_byte_charset= true;
@@ -1982,6 +1989,10 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
}
else
{
+ sortorder->type= sortorder->item->type_handler()->is_packable() ?
+ SORT_FIELD_ATTR::VARIABLE_SIZE :
+ SORT_FIELD_ATTR::FIXED_SIZE;
+
sortorder->item->sortlength(thd, sortorder->item, sortorder);
if (use_strnxfrm(sortorder->item->collation.collation))
{
@@ -1990,7 +2001,8 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
if (sortorder->item->maybe_null)
length++; // Place for NULL marker
}
- set_if_smaller(sortorder->length, thd->variables.max_sort_length);
+ if (sortorder->is_variable_sized())
+ set_if_smaller(sortorder->length, thd->variables.max_sort_length);
length+=sortorder->length;
}
sortorder->field= (Field*) 0; // end marker