From: Tor Didriksen Date: May 23 2011 1:04pm Subject: bzr commit into mysql-trunk branch (tor.didriksen:3101) Bug#11765562 List-Archive: http://lists.mysql.com/commits/137858 X-Bug: 11765562 Message-Id: <20110523130456.B09B637A6@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3238787801415093567==" --===============3238787801415093567== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/didrik/repo/trunk-bug11765562/ based on revid:anitha.gopi@stripped 3101 Tor Didriksen 2011-05-23 Bug#11765562 58545 EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE The function EXPORT_SET(bits,on,off[,separator[,number_of_bits]]) will concatenate (up to) 64*2 -1 strings: on/off and separator. The total length should not be greater than thd->variables.max_allowed_packet. @ mysql-test/r/func_str.result New test case. @ mysql-test/t/func_str.test New test case. @ sql/item_strfunc.cc In Item_func_export_set::val_str, verify that the size of the end result is within reasonable bounds. @ unittest/gunit/item-t.cc New test cases. @ unittest/gunit/test_utils.h Add accessor for handle_called. modified: mysql-test/r/func_str.result mysql-test/t/func_str.test sql/item_strfunc.cc unittest/gunit/item-t.cc unittest/gunit/test_utils.h === modified file 'mysql-test/r/func_str.result' --- a/mysql-test/r/func_str.result 2011-01-13 08:19:52 +0000 +++ b/mysql-test/r/func_str.result 2011-05-23 13:04:52 +0000 @@ -4306,5 +4306,22 @@ FROM_BASE64(TO_BASE64(dt1)) 2011-01-01 02:03:04 DROP TABLE t1; # +# Bug#11765562 58545: +# EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE +# +SELECT @tmp_max:= @@global.max_allowed_packet; +@tmp_max:= @@global.max_allowed_packet +1048576 +SET @@global.max_allowed_packet=1024*1024*1024; +SELECT @@global.max_allowed_packet; +@@global.max_allowed_packet +1073741824 +SELECT CHAR_LENGTH(EXPORT_SET(1,1,1,REPEAT(1,100000000))); +CHAR_LENGTH(EXPORT_SET(1,1,1,REPEAT(1,100000000))) +NULL +Warnings: +Warning 1301 Result of export_set() was larger than max_allowed_packet (1073741824) - truncated +SET @@global.max_allowed_packet:= @tmp_max; +# # End of 5.6 tests # === modified file 'mysql-test/t/func_str.test' --- a/mysql-test/t/func_str.test 2011-01-13 08:19:52 +0000 +++ b/mysql-test/t/func_str.test 2011-05-23 13:04:52 +0000 @@ -1557,5 +1557,23 @@ SELECT FROM_BASE64(TO_BASE64(dt1)) FROM DROP TABLE t1; --echo # +--echo # Bug#11765562 58545: +--echo # EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE +--echo # + +SELECT @tmp_max:= @@global.max_allowed_packet; +SET @@global.max_allowed_packet=1024*1024*1024; +# switching connection to allow the new max_allowed_packet take effect +--connect (newconn, localhost, root,,) + +SELECT @@global.max_allowed_packet; +SELECT CHAR_LENGTH(EXPORT_SET(1,1,1,REPEAT(1,100000000))); + +--connection default +SET @@global.max_allowed_packet:= @tmp_max; +--disconnect newconn + + +--echo # --echo # End of 5.6 tests --echo # === modified file 'sql/item_strfunc.cc' --- a/sql/item_strfunc.cc 2011-05-21 08:25:33 +0000 +++ b/sql/item_strfunc.cc 2011-05-23 13:04:52 +0000 @@ -3437,23 +3437,21 @@ err: String* Item_func_export_set::val_str(String* str) { DBUG_ASSERT(fixed == 1); - ulonglong the_set = (ulonglong) args[0]->val_int(); - String yes_buf, *yes; - yes = args[1]->val_str(&yes_buf); - String no_buf, *no; - no = args[2]->val_str(&no_buf); - String *sep = NULL, sep_buf ; + String yes_buf, no_buf, sep_buf; + const ulonglong the_set = (ulonglong) args[0]->val_int(); + const String *yes= args[1]->val_str(&yes_buf); + const String *no= args[2]->val_str(&no_buf); + const String *sep= NULL; uint num_set_values = 64; - ulonglong mask = 0x1; str->length(0); str->set_charset(collation.collation); /* Check if some argument is a NULL value */ if (args[0]->null_value || args[1]->null_value || args[2]->null_value) { - null_value=1; - return 0; + null_value= true; + return NULL; } /* Arg count can only be 3, 4 or 5 here. This is guaranteed from the @@ -3466,37 +3464,56 @@ String* Item_func_export_set::val_str(St num_set_values=64; if (args[4]->null_value) { - null_value=1; - return 0; + null_value= true; + return NULL; } /* Fall through */ case 4: if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL { - null_value=1; - return 0; + null_value= true; + return NULL; } break; case 3: { /* errors is not checked - assume "," can always be converted */ uint errors; - sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors); + sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, + collation.collation, &errors); sep = &sep_buf; } break; default: DBUG_ASSERT(0); // cannot happen } - null_value=0; + null_value= false; + + const ulong max_allowed_packet= current_thd->variables.max_allowed_packet; + const uint num_separators= num_set_values > 0 ? num_set_values - 1 : 0; + const ulonglong max_total_length= + num_set_values * max(yes->length(), no->length()) + + num_separators * sep->length(); + + if (unlikely(max_total_length > max_allowed_packet)) + { + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_ALLOWED_PACKET_OVERFLOWED, + ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), + func_name(), max_allowed_packet); + null_value= true; + return NULL; + } - for (uint i = 0; i < num_set_values; i++, mask = (mask << 1)) + uint ix; + ulonglong mask; + for (ix= 0, mask=0x1; ix < num_set_values; ++ix, mask = (mask << 1)) { if (the_set & mask) str->append(*yes); else str->append(*no); - if (i != num_set_values - 1) + if (ix != num_separators) str->append(*sep); } return str; === modified file 'unittest/gunit/item-t.cc' --- a/unittest/gunit/item-t.cc 2011-05-13 09:36:13 +0000 +++ b/unittest/gunit/item-t.cc 2011-05-23 13:04:52 +0000 @@ -176,6 +176,88 @@ TEST_F(ItemTest, ItemFuncDesDecrypt) } +TEST_F(ItemTest, ItemFuncExportSet) +{ + String str; + Item *on_string= new Item_string(STRING_WITH_LEN("on"), &my_charset_bin); + Item *off_string= new Item_string(STRING_WITH_LEN("off"), &my_charset_bin); + Item *sep_string= new Item_string(STRING_WITH_LEN(","), &my_charset_bin); + { + // Testing basic functionality. + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(2), + on_string, + off_string, + sep_string, + new Item_int(4)); + EXPECT_FALSE(export_set->fix_fields(thd(), NULL)); + EXPECT_EQ(&str, export_set->val_str(&str)); + EXPECT_STREQ("off,on,off,off", str.c_ptr_safe()); + } + { + // Testing corner case: number_of_bits == zero. + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(2), + on_string, + off_string, + sep_string, + new Item_int(0)); + EXPECT_FALSE(export_set->fix_fields(thd(), NULL)); + EXPECT_EQ(&str, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + } + + /* + Bug#11765562 58545: + EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE + */ + const ulong max_size= 1024; + const ulonglong repeat= max_size / 2; + Item *item_int_repeat= new Item_int(repeat); + Item *string_x= new Item_string(STRING_WITH_LEN("x"), &my_charset_bin); + thd()->variables.max_allowed_packet= max_size; + { + // Testing overflow caused by 'on-string'. + Mock_error_handler error_handler(thd(), ER_WARN_ALLOWED_PACKET_OVERFLOWED); + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(0xff), + new Item_func_repeat(string_x, item_int_repeat), + string_x, + sep_string); + EXPECT_FALSE(export_set->fix_fields(thd(), NULL)); + EXPECT_EQ(NULL, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + EXPECT_EQ(1, error_handler.handle_called()); + } + { + // Testing overflow caused by 'off-string'. + Mock_error_handler error_handler(thd(), ER_WARN_ALLOWED_PACKET_OVERFLOWED); + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(0xff), + string_x, + new Item_func_repeat(string_x, item_int_repeat), + sep_string); + EXPECT_FALSE(export_set->fix_fields(thd(), NULL)); + EXPECT_EQ(NULL, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + EXPECT_EQ(1, error_handler.handle_called()); + } + { + // Testing overflow caused by 'separator-string'. + Mock_error_handler error_handler(thd(), ER_WARN_ALLOWED_PACKET_OVERFLOWED); + Item_func_export_set *export_set= + new Item_func_export_set(new Item_int(0xff), + string_x, + string_x, + new Item_func_repeat(string_x, item_int_repeat)); + EXPECT_FALSE(export_set->fix_fields(thd(), NULL)); + EXPECT_EQ(NULL, export_set->val_str(&str)); + EXPECT_STREQ("", str.c_ptr_safe()); + EXPECT_EQ(1, error_handler.handle_called()); + } +} + + TEST_F(ItemTest, ItemFuncIntDivOverflow) { const char dividend_str[]= === modified file 'unittest/gunit/test_utils.h' --- a/unittest/gunit/test_utils.h 2011-05-13 09:36:13 +0000 +++ b/unittest/gunit/test_utils.h 2011-05-23 13:04:52 +0000 @@ -63,6 +63,8 @@ public: MYSQL_ERROR::enum_warning_level level, const char* msg, MYSQL_ERROR ** cond_hdl); + + int handle_called() const { return m_handle_called; } private: THD *m_thd; uint m_expected_error; --===============3238787801415093567== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/tor.didriksen@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: tor.didriksen@stripped\ # fl212az9qczok5wy # target_branch: file:///export/home/didrik/repo/trunk-bug11765562/ # testament_sha1: 07164b00a8f94e0215eb646927a562d49efceaf1 # timestamp: 2011-05-23 15:04:56 +0200 # base_revision_id: anitha.gopi@stripped\ # ggo3wmzmu8pk3jzo # # Begin bundle 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 --===============3238787801415093567==--