1
1
/*
2
- Copyright (c) 2000, 2016 , Oracle and/or its affiliates. All rights reserved.
2
+ Copyright (c) 2000, 2018 , Oracle and/or its affiliates. All rights reserved.
3
3
4
4
This program is free software; you can redistribute it and/or modify
5
5
it under the terms of the GNU General Public License as published by
@@ -3024,6 +3024,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
3024
3024
db= (char *)start;
3025
3025
query= (char *)(start + db_len + 1 );
3026
3026
q_len= data_len - db_len -1 ;
3027
+
3028
+ if (data_len && (data_len < db_len ||
3029
+ data_len < q_len ||
3030
+ data_len != (db_len + q_len + 1 )))
3031
+ {
3032
+ q_len= 0 ;
3033
+ query= NULL ;
3034
+ DBUG_VOID_RETURN;
3035
+ }
3036
+
3037
+ unsigned int max_length;
3038
+ max_length= (event_len - ((const char *)(end + db_len + 1 ) -
3039
+ (buf - common_header_len)));
3040
+ if (q_len != max_length)
3041
+ {
3042
+ q_len= 0 ;
3043
+ query= NULL ;
3044
+ DBUG_VOID_RETURN;
3045
+ }
3027
3046
/* *
3028
3047
Append the db length at the end of the buffer. This will be used by
3029
3048
Query_cache::send_result_to_client() in case the query cache is On.
@@ -3278,6 +3297,26 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
3278
3297
you.
3279
3298
*/
3280
3299
thd->catalog = catalog_len ? (char *) catalog : (char *)" " ;
3300
+
3301
+ size_t valid_len;
3302
+ bool len_error;
3303
+ bool is_invalid_db_name= validate_string (system_charset_info, db, db_len,
3304
+ &valid_len, &len_error);
3305
+
3306
+ DBUG_PRINT (" debug" ,(" is_invalid_db_name= %s, valid_len=%zu, len_error=%s" ,
3307
+ is_invalid_db_name ? " true" : " false" ,
3308
+ valid_len,
3309
+ len_error ? " true" : " false" ));
3310
+
3311
+ if (is_invalid_db_name || len_error)
3312
+ {
3313
+ rli->report (ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3314
+ ER_THD (thd, ER_SLAVE_FATAL_ERROR),
3315
+ " Invalid database name in Query event." );
3316
+ thd->is_slave_error = true ;
3317
+ goto end;
3318
+ }
3319
+
3281
3320
new_db.length = db_len;
3282
3321
new_db.str = (char *) rpl_filter->get_rewrite_db (db, &new_db.length );
3283
3322
thd->set_db (new_db.str , new_db.length ); /* allocates a copy of 'db' */
@@ -3454,7 +3493,23 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
3454
3493
}
3455
3494
else
3456
3495
thd->variables .collation_database = thd->db_charset ;
3457
-
3496
+
3497
+ {
3498
+ const CHARSET_INFO *cs= thd->charset ();
3499
+ /*
3500
+ We cannot ask for parsing a statement using a character set
3501
+ without state_maps (parser internal data).
3502
+ */
3503
+ if (!cs->state_map )
3504
+ {
3505
+ rli->report (ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3506
+ ER_THD (thd, ER_SLAVE_FATAL_ERROR),
3507
+ " character_set cannot be parsed" );
3508
+ thd->is_slave_error = true ;
3509
+ goto end;
3510
+ }
3511
+ }
3512
+
3458
3513
thd->table_map_for_update = (table_map)table_map_for_update;
3459
3514
thd->set_invoker (&user, &host);
3460
3515
/*
@@ -3898,7 +3953,13 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
3898
3953
*/
3899
3954
break ;
3900
3955
default :
3901
- /* this case is impossible */
3956
+ /*
3957
+ This case is not expected. It can be either an event corruption or an
3958
+ unsupported binary log version.
3959
+ */
3960
+ rli->report (ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3961
+ ER_THD (thd, ER_SLAVE_FATAL_ERROR),
3962
+ " Binlog version not supported" );
3902
3963
DBUG_RETURN (1 );
3903
3964
}
3904
3965
DBUG_RETURN (error);
@@ -4724,6 +4785,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
4724
4785
4725
4786
fields = (char *)field_lens + num_fields;
4726
4787
table_name = fields + field_block_len;
4788
+ if (strlen (table_name) > NAME_LEN)
4789
+ goto err;
4790
+
4727
4791
db = table_name + table_name_len + 1 ;
4728
4792
DBUG_EXECUTE_IF (" simulate_invalid_address" ,
4729
4793
db_len = data_len;);
@@ -5889,6 +5953,13 @@ User_var_log_event(const char* buf, uint event_len,
5889
5953
buf+= description_event->common_header_len +
5890
5954
description_event->post_header_len [USER_VAR_EVENT-1 ];
5891
5955
name_len= uint4korr (buf);
5956
+ /* Avoid reading out of buffer */
5957
+ if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
5958
+ {
5959
+ error= true ;
5960
+ goto err;
5961
+ }
5962
+
5892
5963
name= (char *) buf + UV_NAME_LEN_SIZE;
5893
5964
5894
5965
/*
@@ -5948,8 +6019,11 @@ User_var_log_event(const char* buf, uint event_len,
5948
6019
we keep the flags set to UNDEF_F.
5949
6020
*/
5950
6021
uint bytes_read= ((val + val_len) - start);
5951
- DBUG_ASSERT (bytes_read==data_written ||
5952
- bytes_read==(data_written-1 ));
6022
+ if (bytes_read > event_len)
6023
+ {
6024
+ error= true ;
6025
+ goto err;
6026
+ }
5953
6027
if ((data_written - bytes_read) > 0 )
5954
6028
{
5955
6029
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
@@ -6165,7 +6239,12 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
6165
6239
}
6166
6240
6167
6241
if (!(charset= get_charset (charset_number, MYF (MY_WME))))
6242
+ {
6243
+ rli->report (ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6244
+ ER_THD (thd, ER_SLAVE_FATAL_ERROR),
6245
+ " Invalid character set for User var event" );
6168
6246
return 1 ;
6247
+ }
6169
6248
LEX_STRING user_var_name;
6170
6249
user_var_name.str = name;
6171
6250
user_var_name.length = name_len;
@@ -6186,19 +6265,40 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
6186
6265
{
6187
6266
switch (type) {
6188
6267
case REAL_RESULT:
6268
+ if (val_len != 8 )
6269
+ {
6270
+ rli->report (ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6271
+ ER_THD (thd, ER_SLAVE_FATAL_ERROR),
6272
+ " Invalid variable length at User var event" );
6273
+ return 1 ;
6274
+ }
6189
6275
float8get (real_val, val);
6190
6276
it= new Item_float (real_val, 0 );
6191
6277
val= (char *) &real_val; // Pointer to value in native format
6192
6278
val_len= 8 ;
6193
6279
break ;
6194
6280
case INT_RESULT:
6281
+ if (val_len != 8 )
6282
+ {
6283
+ rli->report (ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6284
+ ER_THD (thd, ER_SLAVE_FATAL_ERROR),
6285
+ " Invalid variable length at User var event" );
6286
+ return 1 ;
6287
+ }
6195
6288
int_val= (longlong) uint8korr (val);
6196
6289
it= new Item_int (int_val);
6197
6290
val= (char *) &int_val; // Pointer to value in native format
6198
6291
val_len= 8 ;
6199
6292
break ;
6200
6293
case DECIMAL_RESULT:
6201
6294
{
6295
+ if (val_len < 3 )
6296
+ {
6297
+ rli->report (ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6298
+ ER_THD (thd, ER_SLAVE_FATAL_ERROR),
6299
+ " Invalid variable length at User var event" );
6300
+ return 1 ;
6301
+ }
6202
6302
Item_decimal *dec= new Item_decimal ((uchar*) val+2 , val[0 ], val[1 ]);
6203
6303
it= dec;
6204
6304
val= (char *)dec->val_decimal (NULL );
@@ -7646,6 +7746,15 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
7646
7746
DBUG_PRINT (" debug" , (" Reading from %p" , ptr_after_width));
7647
7747
m_width = net_field_length (&ptr_after_width);
7648
7748
DBUG_PRINT (" debug" , (" m_width=%lu" , m_width));
7749
+ /* Avoid reading out of buffer */
7750
+ if (static_cast <unsigned int >((ptr_after_width +
7751
+ (m_width + 7 ) / 8 ) -
7752
+ (uchar*)buf) > event_len)
7753
+ {
7754
+ m_cols.bitmap = NULL ;
7755
+ DBUG_VOID_RETURN;
7756
+ }
7757
+
7649
7758
/* if bitmap_init fails, catched in is_valid() */
7650
7759
if (likely (!bitmap_init (&m_cols,
7651
7760
m_width <= sizeof (m_bitbuf)*8 ? m_bitbuf : NULL ,
@@ -7694,7 +7803,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
7694
7803
7695
7804
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
7696
7805
7697
- size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
7806
+ size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
7807
+ if (read_size > event_len)
7808
+ {
7809
+ DBUG_VOID_RETURN;
7810
+ }
7811
+ size_t const data_size= event_len - read_size;
7698
7812
DBUG_PRINT (" info" ,(" m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu" ,
7699
7813
m_table_id, m_flags, m_width, (ulong) data_size));
7700
7814
0 commit comments