summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKailasnath Nagarkar <kailasnath.nagarkar@oracle.com>2016-09-02 15:13:52 +0530
committerKailasnath Nagarkar <kailasnath.nagarkar@oracle.com>2016-09-02 15:13:52 +0530
commit91ddaff991d745d6b2308342a2555d302a13a481 (patch)
treed7a3ac76f36145196d77b40c9ec6df955453bae7
parentaeab9d6b417871a2893df710c690be0de53e0c7a (diff)
downloadmariadb-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.
-rw-r--r--sql/field.cc15
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);
+ }
}
}