mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-40147 MSAN: use-of-uninitialized-value in my_time_compare
Field::get_date and Item::get_date can return true and not have their ltime pointer structure initialized. This was the case with Field_vers_trx_id::get_date. Type_handler_time_common::stored_field_cmp_to_item rather than doing a my_time_compare on uninitialized values can return a non-equality (!=0) value for when the fetching of Field or Item fails and avoid the call to my_time_compare. Added checks for other invalid results before being passed to my_time_compare. Add nonnull as an attribute on my_time_compare and the unpack_time function it used. Also pack_time since related and it obviously requires a non-null argument. Reviewed by: Alexey Midenkov
This commit is contained in:
@@ -611,3 +611,21 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
disconnect con1;
|
||||
connection default;
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-40147 MSAN: use-of-uninitialized-value in my_time_compare
|
||||
#
|
||||
create table t (
|
||||
a int,
|
||||
row_start bigint unsigned generated always as row start,
|
||||
row_end bigint unsigned generated always as row end,
|
||||
period for system_time (row_start, row_end)
|
||||
) with system versioning engine=InnoDB;
|
||||
insert into t () values ();
|
||||
analyze table t persistent for all;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t analyze status Engine-independent statistics collected
|
||||
test.t analyze status OK
|
||||
select * from t where row_end > current_time();
|
||||
ERROR HY000: TRX_ID ... not found in `mysql.transaction_registry`
|
||||
drop table t;
|
||||
# End of 10.11 tests
|
||||
|
||||
@@ -643,3 +643,26 @@ alter table xx;
|
||||
--disconnect con1
|
||||
--connection default
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-40147 MSAN: use-of-uninitialized-value in my_time_compare
|
||||
--echo #
|
||||
|
||||
create table t (
|
||||
a int,
|
||||
row_start bigint unsigned generated always as row start,
|
||||
row_end bigint unsigned generated always as row end,
|
||||
period for system_time (row_start, row_end)
|
||||
) with system versioning engine=InnoDB;
|
||||
|
||||
insert into t () values ();
|
||||
|
||||
analyze table t persistent for all;
|
||||
|
||||
--replace_regex /TRX_ID \d+/TRX_ID .../
|
||||
--error ER_VERS_NO_TRX_ID
|
||||
select * from t where row_end > current_time();
|
||||
|
||||
drop table t;
|
||||
|
||||
--echo # End of 10.11 tests
|
||||
|
||||
@@ -121,7 +121,8 @@ int append_interval(String *str, interval_type int_type,
|
||||
*/
|
||||
bool calc_time_diff(const MYSQL_TIME *l_time1, const MYSQL_TIME *l_time2,
|
||||
int lsign, MYSQL_TIME *l_time3, date_mode_t fuzzydate);
|
||||
int my_time_compare(const MYSQL_TIME *a, const MYSQL_TIME *b);
|
||||
int my_time_compare(const MYSQL_TIME *a, const MYSQL_TIME *b)
|
||||
__attribute__((nonnull));
|
||||
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
|
||||
|
||||
void calc_time_from_sec(MYSQL_TIME *to, ulong seconds, ulong microseconds);
|
||||
@@ -183,8 +184,10 @@ check_date_with_warn(THD *thd, const MYSQL_TIME *ltime,
|
||||
|
||||
bool adjust_time_range_with_warn(THD *thd, MYSQL_TIME *ltime, uint dec);
|
||||
|
||||
longlong pack_time(const MYSQL_TIME *my_time);
|
||||
longlong pack_time(const MYSQL_TIME *my_time)
|
||||
__attribute__((nonnull));
|
||||
void unpack_time(longlong packed, MYSQL_TIME *my_time,
|
||||
enum_mysql_timestamp_type ts_type);
|
||||
enum_mysql_timestamp_type ts_type)
|
||||
__attribute__((nonnull));
|
||||
|
||||
#endif /* SQL_TIME_INCLUDED */
|
||||
|
||||
@@ -8951,7 +8951,7 @@ Type_handler_temporal_result::Item_const_eq(const Item_const *a,
|
||||
{
|
||||
const MYSQL_TIME *ta= a->const_ptr_mysql_time();
|
||||
const MYSQL_TIME *tb= b->const_ptr_mysql_time();
|
||||
return !my_time_compare(ta, tb) &&
|
||||
return ta && tb && !my_time_compare(ta, tb) &&
|
||||
(!binary_cmp ||
|
||||
a->get_type_all_attributes_from_const()->decimals ==
|
||||
b->get_type_all_attributes_from_const()->decimals);
|
||||
@@ -9107,8 +9107,9 @@ int Type_handler_temporal_with_date::stored_field_cmp_to_item(THD *thd,
|
||||
Item *item) const
|
||||
{
|
||||
MYSQL_TIME field_time, item_time, item_time2, *item_time_cmp= &item_time;
|
||||
field->get_date(&field_time, Datetime::Options(TIME_INVALID_DATES, thd));
|
||||
item->get_date(thd, &item_time, Datetime::Options(TIME_INVALID_DATES, thd));
|
||||
if (field->get_date(&field_time, Datetime::Options(TIME_INVALID_DATES, thd))
|
||||
|| item->get_date(thd, &item_time, Datetime::Options(TIME_INVALID_DATES, thd)))
|
||||
return -1;
|
||||
if (item_time.time_type == MYSQL_TIMESTAMP_TIME &&
|
||||
time_to_datetime(thd, &item_time, item_time_cmp= &item_time2))
|
||||
return 1;
|
||||
@@ -9121,8 +9122,9 @@ int Type_handler_time_common::stored_field_cmp_to_item(THD *thd,
|
||||
Item *item) const
|
||||
{
|
||||
MYSQL_TIME field_time, item_time;
|
||||
field->get_date(&field_time, Time::Options(thd));
|
||||
item->get_date(thd, &item_time, Time::Options(thd));
|
||||
if (field->get_date(&field_time, Time::Options(thd))
|
||||
|| item->get_date(thd, &item_time, Time::Options(thd)))
|
||||
return -1; /* !=0 is important, and avoid my_time_compare */
|
||||
return my_time_compare(&field_time, &item_time);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user