diff options
author | Georgi Kodinov <joro@sun.com> | 2009-08-24 15:28:03 +0300 |
---|---|---|
committer | Georgi Kodinov <joro@sun.com> | 2009-08-24 15:28:03 +0300 |
commit | 7492d622e44d7d3fd424bd24fd53131fe06d1c22 (patch) | |
tree | 2b8b30e6a09499348e100ef83b6a9e47dd68a44b /sql/opt_range.cc | |
parent | 152943f39f487795f3d1d6910d1ee9f736feae44 (diff) | |
download | mariadb-git-7492d622e44d7d3fd424bd24fd53131fe06d1c22.tar.gz |
Bug #37044: Read overflow in opt_range.cc found during "make test"
The code was using a special global buffer for the value of IS NULL ranges.
This was not always long enough to be copied by a regular memcpy. As a
result read buffer overflows may occur.
Fixed by setting the null byte to 1 and setting the rest of the field disk image
to NULL with a bzero (instead of relying on the buffer and memcpy()).
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d007009d62c..778fc418392 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -8308,11 +8308,21 @@ get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree, return FALSE; uint field_length= cur_part->store_length; - if ((cur_range->maybe_null && + if (cur_range->maybe_null && cur_range->min_value[0] && cur_range->max_value[0]) - || - (memcmp(cur_range->min_value, cur_range->max_value, field_length) == 0)) - { /* cur_range specifies 'IS NULL' or an equality condition. */ + { + /* + cur_range specifies 'IS NULL'. In this case the argument points to a "null value" (is_null_string) + that may not always be long enough for a direct memcpy to a field. + */ + DBUG_ASSERT (field_length > 0); + *key_ptr= 1; + bzero(key_ptr+1,field_length-1); + key_ptr+= field_length; + *key_infix_len+= field_length; + } + else if (memcmp(cur_range->min_value, cur_range->max_value, field_length) == 0) + { /* cur_range specifies an equality condition. */ memcpy(key_ptr, cur_range->min_value, field_length); key_ptr+= field_length; *key_infix_len+= field_length; |