~ubuntu-branches/ubuntu/lucid/mysql-dfsg-5.1/lucid-security

« back to all changes in this revision

Viewing changes to sql/sql_class.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 22:33:55 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120222223355-or06x1euyk8n0ldi
Tags: 5.1.61-0ubuntu0.10.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496
* Dropped patches unnecessary with 5.1.61:
  - debian/patches/90_mysql_safer_strmov.dpatch
  - debian/patches/51_ssl_test_certs.dpatch
  - debian/patches/52_CVE-2009-4030.dpatch
  - debian/patches/53_CVE-2009-4484.dpatch
  - debian/patches/54_CVE-2008-7247.dpatch
  - debian/patches/55_CVE-2010-1621.dpatch
  - debian/patches/56_CVE-2010-1850.dpatch
  - debian/patches/57_CVE-2010-1849.dpatch
  - debian/patches/58_CVE-2010-1848.dpatch
  - debian/patches/59_CVE-2010-1626.dpatch
  - debian/patches/60_CVE-2010-2008.dpatch
  - debian/patches/60_CVE-2010-3677.dpatch
  - debian/patches/60_CVE-2010-3678.dpatch
  - debian/patches/60_CVE-2010-3679.dpatch
  - debian/patches/60_CVE-2010-3680.dpatch
  - debian/patches/60_CVE-2010-3681.dpatch
  - debian/patches/60_CVE-2010-3682.dpatch
  - debian/patches/60_CVE-2010-3683.dpatch
  - debian/patches/60_CVE-2010-3833.dpatch
  - debian/patches/60_CVE-2010-3834.dpatch
  - debian/patches/60_CVE-2010-3835.dpatch
  - debian/patches/60_CVE-2010-3836.dpatch
  - debian/patches/60_CVE-2010-3837.dpatch
  - debian/patches/60_CVE-2010-3838.dpatch
  - debian/patches/60_CVE-2010-3839.dpatch
  - debian/patches/60_CVE-2010-3840.dpatch
  - debian/patches/61_disable_longfilename_test.dpatch
  - debian/patches/62_alter_table_fix.dpatch
  - debian/patches/63_cherrypick-upstream-49479.dpatch
  - debian/patches/10_readline_build_fix.dpatch
* debian/mysql-client-5.1.docs: removed EXCEPTIONS-CLIENT file
* debian/mysql-server-5.1.docs,debian/libmysqlclient16.docs,
  debian/libmysqlclient-dev.docs: removed, no longer necessary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
1
/*
 
2
   Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2
3
 
3
4
   This program is free software; you can redistribute it and/or modify
4
5
   it under the terms of the GNU General Public License as published by
11
12
 
12
13
   You should have received a copy of the GNU General Public License
13
14
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
 
15
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 
16
*/
16
17
 
17
18
/*****************************************************************************
18
19
**
91
92
 
92
93
bool Key_part_spec::operator==(const Key_part_spec& other) const
93
94
{
94
 
  return length == other.length && !strcmp(field_name, other.field_name);
 
95
  return length == other.length &&
 
96
         !my_strcasecmp(system_charset_info, field_name,
 
97
                        other.field_name);
95
98
}
96
99
 
97
100
/**
284
287
  return (void **) &thd->ha_data[hton->slot].ha_ptr;
285
288
}
286
289
 
 
290
 
 
291
/**
 
292
  Provide a handler data getter to simplify coding
 
293
*/
 
294
extern "C"
 
295
void *thd_get_ha_data(const THD *thd, const struct handlerton *hton)
 
296
{
 
297
  return *thd_ha_data(thd, hton);
 
298
}
 
299
 
 
300
 
 
301
/**
 
302
  Provide a handler data setter to simplify coding
 
303
  @see thd_set_ha_data() definition in plugin.h
 
304
*/
 
305
extern "C"
 
306
void thd_set_ha_data(THD *thd, const struct handlerton *hton,
 
307
                     const void *ha_data)
 
308
{
 
309
  plugin_ref *lock= &thd->ha_data[hton->slot].lock;
 
310
  if (ha_data && !*lock)
 
311
    *lock= ha_lock_engine(NULL, (handlerton*) hton);
 
312
  else if (!ha_data && *lock)
 
313
  {
 
314
    plugin_unlock(NULL, *lock);
 
315
    *lock= NULL;
 
316
  }
 
317
  *thd_ha_data(thd, hton)= (void*) ha_data;
 
318
}
 
319
 
 
320
 
287
321
extern "C"
288
322
long long thd_test_options(const THD *thd, long long test_options)
289
323
{
376
410
    str.append(proc_info);
377
411
  }
378
412
 
 
413
  pthread_mutex_lock(&thd->LOCK_thd_data);
 
414
 
379
415
  if (thd->query())
380
416
  {
381
417
    if (max_query_len < 1)
385
421
    str.append('\n');
386
422
    str.append(thd->query(), len);
387
423
  }
 
424
 
 
425
  pthread_mutex_unlock(&thd->LOCK_thd_data);
 
426
 
388
427
  if (str.c_ptr_safe() == buffer)
389
428
    return buffer;
390
429
 
610
649
  is_slave_error= thread_specific_used= FALSE;
611
650
  hash_clear(&handler_tables_hash);
612
651
  tmp_table=0;
613
 
  used_tables=0;
614
652
  cuted_fields= sent_row_count= row_count= 0L;
615
653
  limit_found_rows= 0;
616
654
  row_count_func= -1;
700
738
  thr_lock_owner_init(&main_lock_id, &lock_info);
701
739
 
702
740
  m_internal_handler= NULL;
 
741
  m_binlog_invoker= FALSE;
 
742
  memset(&invoker_user, 0, sizeof(invoker_user));
 
743
  memset(&invoker_host, 0, sizeof(invoker_host));
703
744
}
704
745
 
705
746
 
720
761
bool THD::handle_error(uint sql_errno, const char *message,
721
762
                       MYSQL_ERROR::enum_warning_level level)
722
763
{
723
 
  if (!m_internal_handler)
724
 
    return FALSE;
725
 
 
726
764
  for (Internal_error_handler *error_handler= m_internal_handler;
727
765
       error_handler;
728
 
       error_handler= m_internal_handler->m_prev_internal_handler)
 
766
       error_handler= error_handler->m_prev_internal_handler)
729
767
  {
730
768
    if (error_handler->handle_error(sql_errno, message, level, this))
731
 
    return TRUE;
 
769
      return TRUE;
732
770
  }
733
771
 
734
772
  return FALSE;
735
773
}
736
774
 
737
775
 
738
 
void THD::pop_internal_handler()
 
776
Internal_error_handler *THD::pop_internal_handler()
739
777
{
740
778
  DBUG_ASSERT(m_internal_handler != NULL);
 
779
  Internal_error_handler *popped_handler= m_internal_handler;
741
780
  m_internal_handler= m_internal_handler->m_prev_internal_handler;
 
781
  return popped_handler;
742
782
}
743
783
 
744
784
extern "C"
1025
1065
 
1026
1066
  while (to != end)
1027
1067
    *(to++)+= *(from++);
 
1068
 
 
1069
  to_var->bytes_received+= from_var->bytes_received;
 
1070
  to_var->bytes_sent+= from_var->bytes_sent;
1028
1071
}
1029
1072
 
1030
1073
/*
1050
1093
 
1051
1094
  while (to != end)
1052
1095
    *(to++)+= *(from++) - *(dec++);
 
1096
 
 
1097
  to_var->bytes_received+= from_var->bytes_received - dec_var->bytes_received;;
 
1098
  to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent;
1053
1099
}
1054
1100
 
1055
1101
 
1150
1196
  return 0;
1151
1197
}
1152
1198
 
 
1199
/*
 
1200
  Remove the thread specific info (THD and mem_root pointer) stored during
 
1201
  store_global call for this thread.
 
1202
*/
 
1203
bool THD::restore_globals()
 
1204
{
 
1205
  /*
 
1206
    Assert that thread_stack is initialized: it's necessary to be able
 
1207
    to track stack overrun.
 
1208
  */
 
1209
  DBUG_ASSERT(thread_stack);
 
1210
  
 
1211
  /* Undocking the thread specific data. */
 
1212
  my_pthread_setspecific_ptr(THR_THD, NULL);
 
1213
  my_pthread_setspecific_ptr(THR_MALLOC, NULL);
 
1214
  
 
1215
  return 0;
 
1216
}
 
1217
 
1153
1218
 
1154
1219
/*
1155
1220
  Cleanup after query.
1201
1266
  where= THD::DEFAULT_WHERE;
1202
1267
  /* reset table map for multi-table update */
1203
1268
  table_map_for_update= 0;
 
1269
  m_binlog_invoker= FALSE;
1204
1270
}
1205
1271
 
1206
1272
 
1796
1862
  else
1797
1863
    (void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option);
1798
1864
 
1799
 
  if (opt_secure_file_priv &&
1800
 
      strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv)))
 
1865
  if (!is_secure_file_path(path))
1801
1866
  {
1802
1867
    /* Write only allowed to dir or subdir specified by secure_file_priv */
1803
1868
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
1964
2029
      const char *from_end_pos;
1965
2030
      const char *error_pos;
1966
2031
      uint32 bytes;
1967
 
      bytes= well_formed_copy_nchars(write_cs, cvt_buff, sizeof(cvt_buff),
 
2032
      uint64 estimated_bytes=
 
2033
        ((uint64) res->length() / res->charset()->mbminlen + 1) *
 
2034
        write_cs->mbmaxlen + 1;
 
2035
      set_if_smaller(estimated_bytes, UINT_MAX32);
 
2036
      if (cvt_str.realloc((uint32) estimated_bytes))
 
2037
      {
 
2038
        my_error(ER_OUTOFMEMORY, MYF(0), (uint32) estimated_bytes);
 
2039
        goto err;
 
2040
      }
 
2041
 
 
2042
      bytes= well_formed_copy_nchars(write_cs, (char *) cvt_str.ptr(),
 
2043
                                     cvt_str.alloced_length(),
1968
2044
                                     res->charset(), res->ptr(), res->length(),
1969
 
                                     sizeof(cvt_buff),
 
2045
                                     UINT_MAX32, // copy all input chars,
 
2046
                                                 // i.e. ignore nchars parameter
1970
2047
                                     &well_formed_error_pos,
1971
2048
                                     &cannot_convert_error_pos,
1972
2049
                                     &from_end_pos);
1982
2059
                            ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
1983
2060
                            ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
1984
2061
                            "string", printable_buff,
1985
 
                            item->name, row_count);
 
2062
                            item->name, static_cast<long>(row_count));
 
2063
      }
 
2064
      else if (from_end_pos < res->ptr() + res->length())
 
2065
      { 
 
2066
        /*
 
2067
          result is longer than UINT_MAX32 and doesn't fit into String
 
2068
        */
 
2069
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
2070
                            WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
 
2071
                            item->full_name(), static_cast<long>(row_count));
1986
2072
      }
1987
2073
      cvt_str.length(bytes);
1988
2074
      res= &cvt_str;
3096
3182
  }
3097
3183
#endif
3098
3184
  
 
3185
  backup->count_cuted_fields= count_cuted_fields;
3099
3186
  backup->options=         options;
3100
3187
  backup->in_sub_stmt=     in_sub_stmt;
3101
3188
  backup->enable_slow_log= enable_slow_log;
3133
3220
 
3134
3221
void THD::restore_sub_statement_state(Sub_statement_state *backup)
3135
3222
{
 
3223
  DBUG_ENTER("THD::restore_sub_statement_state");
3136
3224
#ifndef EMBEDDED_LIBRARY
3137
3225
  /* BUG#33029, if we are replicating from a buggy master, restore
3138
3226
     auto_inc_intervals_forced so that the top statement can use the
3159
3247
    /* ha_release_savepoint() never returns error. */
3160
3248
    (void)ha_release_savepoint(this, sv);
3161
3249
  }
 
3250
  count_cuted_fields= backup->count_cuted_fields;
3162
3251
  transaction.savepoints= backup->savepoints;
3163
3252
  options=          backup->options;
3164
3253
  in_sub_stmt=      backup->in_sub_stmt;
3188
3277
  */
3189
3278
  examined_row_count+= backup->examined_row_count;
3190
3279
  cuted_fields+=       backup->cuted_fields;
 
3280
  DBUG_VOID_RETURN;
3191
3281
}
3192
3282
 
3193
3283
 
3208
3298
  pthread_mutex_unlock(&LOCK_thd_data);
3209
3299
}
3210
3300
 
 
3301
void THD::get_definer(LEX_USER *definer)
 
3302
{
 
3303
  binlog_invoker();
 
3304
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
3305
  if (slave_thread && has_invoker())
 
3306
  {
 
3307
    definer->user = invoker_user;
 
3308
    definer->host= invoker_host;
 
3309
    definer->password.str= NULL;
 
3310
    definer->password.length= 0;
 
3311
  }
 
3312
  else
 
3313
#endif
 
3314
    get_default_definer(this, definer);
 
3315
}
 
3316
 
3211
3317
 
3212
3318
/**
3213
3319
  Mark transaction to rollback and mark error as fatal to a sub-statement.
3296
3402
    xs->xa_state=xa_state;
3297
3403
    xs->xid.set(xid);
3298
3404
    xs->in_thd=0;
 
3405
    xs->rm_error=0;
3299
3406
    res=my_hash_insert(&xid_cache, (uchar*)xs);
3300
3407
  }
3301
3408
  pthread_mutex_unlock(&LOCK_xid_cache);
3306
3413
bool xid_cache_insert(XID_STATE *xid_state)
3307
3414
{
3308
3415
  pthread_mutex_lock(&LOCK_xid_cache);
3309
 
  DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
3310
 
                          xid_state->xid.key_length())==0);
3311
 
  my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
 
3416
  if (hash_search(&xid_cache, xid_state->xid.key(), xid_state->xid.key_length()))
 
3417
  {
 
3418
    pthread_mutex_unlock(&LOCK_xid_cache);
 
3419
    my_error(ER_XAER_DUPID, MYF(0));
 
3420
    return TRUE;
 
3421
  }
 
3422
  my_bool res= my_hash_insert(&xid_cache, (uchar*)xid_state);
3312
3423
  pthread_mutex_unlock(&LOCK_xid_cache);
3313
3424
  return res;
3314
3425
}
3766
3877
    if (stmt_end)
3767
3878
    {
3768
3879
      pending->set_flags(Rows_log_event::STMT_END_F);
3769
 
      pending->flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
3770
3880
      binlog_table_maps= 0;
3771
3881
    }
3772
3882
 
3894
4004
    {
3895
4005
      Query_log_event qinfo(this, query_arg, query_len, is_trans, suppress_use,
3896
4006
                            errcode);
3897
 
      qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
3898
4007
      /*
3899
4008
        Binlog table maps will be irrelevant after a Query_log_event
3900
4009
        (they are just removed on the slave side) so after the query