summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-08-11 12:11:59 +0200
committerSergei Golubchik <serg@mariadb.org>2018-08-11 12:19:46 +0200
commit3ff0801c7397e3ae5fc538ffca3d58891cd4f27b (patch)
tree89524f2af473f00e1dddc247fa37ede2fe95349c
parentad577091edf288e549c730933c514852b471991c (diff)
downloadmariadb-git-3ff0801c7397e3ae5fc538ffca3d58891cd4f27b.tar.gz
MDEV-16810 AddressSanitizer: stack-buffer-overflow in int10_to_str
truncate incorrect values in convert_period_to_month() so that PERIOD_DIFF never returns a value outside of 2^23 range. And, for safety, increase buffer sizes for int10_to_str to be sufficienly big for any int10_to_str result.
-rw-r--r--mysql-test/r/func_time.result3
-rw-r--r--mysql-test/t/func_time.test4
-rw-r--r--sql/protocol.cc8
-rw-r--r--sql/sql_time.cc2
4 files changed, 12 insertions, 5 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index cffed8eae5b..3f0d99e1315 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -2657,6 +2657,9 @@ SEC_TO_TIME(MAKEDATE(0,RAND(~0)))
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '20000101'
+SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'));
+PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'))
+24257
#
# End of 5.5 tests
#
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 8323bd30d2c..361eff170fb 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1629,6 +1629,10 @@ DO TO_DAYS(SEC_TO_TIME(MAKEDATE('',RAND(~('')))));
SELECT TO_DAYS(SEC_TO_TIME(MAKEDATE(0,RAND(~0))));
SELECT SEC_TO_TIME(MAKEDATE(0,RAND(~0)));
+#
+# MDEV-16810 AddressSanitizer: stack-buffer-overflow in int10_to_str
+#
+SELECT PERIOD_DIFF(2018, AES_ENCRYPT('Rae Bareli', 'Rae Bareli'));
--echo #
--echo # End of 5.5 tests
diff --git a/sql/protocol.cc b/sql/protocol.cc
index ac9fb1e9384..8602d9131c1 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -643,7 +643,7 @@ uchar *net_store_data(uchar *to, const uchar *from, size_t length)
uchar *net_store_data(uchar *to,int32 from)
{
- char buff[20];
+ char buff[22];
uint length=(uint) (int10_to_str(from,buff,10)-buff);
to=net_store_length_fast(to,length);
memcpy(to,buff,length);
@@ -1060,7 +1060,7 @@ bool Protocol_text::store_tiny(longlong from)
DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((int) from, buff, -10) - buff));
}
@@ -1074,7 +1074,7 @@ bool Protocol_text::store_short(longlong from)
field_types[field_pos] == MYSQL_TYPE_SHORT);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((int) from, buff, -10) -
buff));
@@ -1089,7 +1089,7 @@ bool Protocol_text::store_long(longlong from)
field_types[field_pos] == MYSQL_TYPE_LONG);
field_pos++;
#endif
- char buff[20];
+ char buff[22];
return net_store_data((uchar*) buff,
(size_t) (int10_to_str((long int)from, buff,
(from <0)?-10:10)-buff));
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index d912a7b78d6..33bb9a460b0 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -190,7 +190,7 @@ bool get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
ulong convert_period_to_month(ulong period)
{
ulong a,b;
- if (period == 0)
+ if (period == 0 || period > 999912)
return 0L;
if ((a=period/100) < YY_PART_YEAR)
a+=2000;