From: Tor Didriksen Date: May 25 2011 2:19pm Subject: bzr commit into mysql-trunk branch (tor.didriksen:3112) Bug#11765562 List-Archive: http://lists.mysql.com/commits/138089 X-Bug: 11765562 Message-Id: <20110525141958.CED66222@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2310118192855321867==" --===============2310118192855321867== 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 3112 Tor Didriksen 2011-05-25 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-25 14:19:53 +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-25 14:19:53 +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-25 14:19:53 +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-25 14:19:53 +0000 @@ -176,6 +176,89 @@ 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); + String * const null_string= NULL; + 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_string, 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_string, 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_string, 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-25 14:19:53 +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; --===============2310118192855321867== 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\ # tm9nda1r50v8l31v # target_branch: file:///export/home/didrik/repo/trunk-bug11765562/ # testament_sha1: c1f9245d224bdd594c1df374c4ff318a5ba1db7e # timestamp: 2011-05-25 16:19:58 +0200 # base_revision_id: anitha.gopi@stripped\ # x97pcil75467b4np # # Begin bundle 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 --===============2310118192855321867==--