Skip to content

Commit 7ce304d

Browse files
committed
Bug#18487951 - QUERY_CACHE_MIN_RES_UNIT SET TO ZERO, CRASHES IN QUERY_CACHE::FIND_BIN
Valid min value for query_cache_min_res_unit is 512. But attempt to set value greater than or equal to the ULONG_MAX(max value) is resulting query_cache_min_res_unit value to 0. This result in crash while searching for memory block lesser than the valid min value to store query results. Free memory blocks in query cache are stored in bins according to their size. The bins are stored in size descending order. For the memory block request the appropriate bin is searched using binary search algorithm. The minimum free memory block request expected is 512 bytes. And the appropriate bin is searched for block greater than or equals to 512 bytes. Because of the bug the query_cache_min_res_unit is set to 0. Due to which there is a chance of request for memory blocks lesser than the minimum size in free memory block bins. Search for bin for this invalid input size fails and returns garbage index. Accessing bins array element with this index is causing the issue reported. The valid value range for the query_cache_min_res_unit is 512 to ULONG_MAX(when value is greater than the max allowed value, max allowed value is used i.e ULONG_MAX). While setting result unit block size (query_cache_min_res_unit), size is memory aligned by using a macro ALIGN_SIZE. The ALIGN_SIZE logic is as below, (input_size + sizeof(double) - 1) & ~(sizeof(double) - 1) For unsigned long type variable when input_size is greater than equal to ULONG_MAX-(sizeof(double)-1), above expression is resulting in value 0. Fix: ----- Comparing value set for query_cache_min_res_unit with max aligned value which can be stored in ulong type variable. If it is greater then setting it to the max aligned value for ulong type variable.
1 parent 7c5d18e commit 7ce304d

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

sql/sql_cache.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2013, 2015, Oracle and/or its affiliates. All rights
2+
reserved.
23
34
This program is free software; you can redistribute it and/or modify
45
it under the terms of the GNU General Public License as published by
@@ -399,6 +400,9 @@ TODO list:
399400
#define QC_DEBUG_SYNC(name)
400401
#endif
401402

403+
// Max aligned size for ulong type query_cache_min_res_unit.
404+
static const ulong max_aligned_min_res_unit_size= ((ULONG_MAX) &
405+
(~(sizeof(double) - 1)));
402406

403407
/**
404408
Thread state to be used when the query cache lock needs to be acquired.
@@ -1158,6 +1162,9 @@ ulong Query_cache::set_min_res_unit(ulong size)
11581162
{
11591163
if (size < min_allocation_unit)
11601164
size= min_allocation_unit;
1165+
else if (size > max_aligned_min_res_unit_size)
1166+
size= max_aligned_min_res_unit_size;
1167+
11611168
return (min_result_data_size= ALIGN_SIZE(size));
11621169
}
11631170

0 commit comments

Comments
 (0)