diff options
author | Kailasnath Nagarkar <kailasnath.nagarkar@oracle.com> | 2016-09-02 15:13:52 +0530 |
---|---|---|
committer | Kailasnath Nagarkar <kailasnath.nagarkar@oracle.com> | 2016-09-02 15:13:52 +0530 |
commit | 91ddaff991d745d6b2308342a2555d302a13a481 (patch) | |
tree | d7a3ac76f36145196d77b40c9ec6df955453bae7 /sql/field.cc | |
parent | aeab9d6b417871a2893df710c690be0de53e0c7a (diff) | |
download | mariadb-git-91ddaff991d745d6b2308342a2555d302a13a481.tar.gz |
Bug #24489302 : ZEROFILL CAUSE MEMORY-CORRUPTION AND CRASH
ISSUE: Heap corruption occurs and hence mysql server
terminates abnormally in String variable destructor
when ZEROFILL is used for a column.
Though the abnormal termination is observed in the
String destructor, heap corruption occurs at earlier
stage when function Field_num::prepend_zeros() is called.
This function, prepends zeros to the actual data and
works on entire field length. Since the allocated memory
could be less than the field length, heap corruption occurs.
Later, when String destructor tries to free heap, the server
terminates abnormally since the heap is corrupt.
SOLUTION: In Field_num::prepend_zeros() function, if allocated memory
is less than the field length, re-allocate memory enough to
hold field length size data.
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/sql/field.cc b/sql/field.cc index 3ca072e7771..15571afefb8 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1130,12 +1130,15 @@ void Field_num::prepend_zeros(String *value) int diff; if ((diff= (int) (field_length - value->length())) > 0) { - bmove_upp((uchar*) value->ptr()+field_length, - (uchar*) value->ptr()+value->length(), - value->length()); - bfill((uchar*) value->ptr(),diff,'0'); - value->length(field_length); - (void) value->c_ptr_quick(); // Avoid warnings in purify + const bool error= value->realloc(field_length); + if (!error) + { + bmove_upp((uchar*) value->ptr()+field_length, + (uchar*) value->ptr()+value->length(), + value->length()); + bfill((uchar*) value->ptr(),diff,'0'); + value->length(field_length); + } } } |