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

« back to all changes in this revision

Viewing changes to sql/sql_prepare.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 (C) 1995-2002 MySQL AB
 
1
/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
/**
17
17
  @file
263
263
                                          &stmt->lex->param_list,
264
264
                                          Protocol::SEND_EOF);
265
265
  }
266
 
  /* Flag that a response has already been sent */
267
 
  thd->main_da.disable_status();
 
266
 
 
267
  if (!error)
 
268
    /* Flag that a response has already been sent */
 
269
    thd->main_da.disable_status();
 
270
 
268
271
  DBUG_RETURN(error);
269
272
}
270
273
#else
702
705
}
703
706
 
704
707
#ifndef EMBEDDED_LIBRARY
 
708
 
 
709
/**
 
710
  Check whether this parameter data type is compatible with long data.
 
711
  Used to detect whether a long data stream has been supplied to a
 
712
  incompatible data type.
 
713
*/
 
714
inline bool is_param_long_data_type(Item_param *param)
 
715
{
 
716
  return ((param->param_type >= MYSQL_TYPE_TINY_BLOB) &&
 
717
          (param->param_type <= MYSQL_TYPE_STRING));
 
718
}
 
719
 
 
720
 
705
721
/**
706
722
  Routines to assign parameters from data supplied by the client.
707
723
 
771
787
          DBUG_RETURN(1);
772
788
      }
773
789
    }
 
790
    /*
 
791
      A long data stream was supplied for this parameter marker.
 
792
      This was done after prepare, prior to providing a placeholder
 
793
      type (the types are supplied at execute). Check that the
 
794
      supplied type of placeholder can accept a data stream.
 
795
    */
 
796
    else if (! is_param_long_data_type(param))
 
797
      DBUG_RETURN(1);
774
798
    res= param->query_val_str(&str);
775
799
    if (param->convert_str_value(thd))
776
800
      DBUG_RETURN(1);                           /* out of memory */
809
833
          DBUG_RETURN(1);
810
834
      }
811
835
    }
 
836
    /*
 
837
      A long data stream was supplied for this parameter marker.
 
838
      This was done after prepare, prior to providing a placeholder
 
839
      type (the types are supplied at execute). Check that the
 
840
      supplied type of placeholder can accept a data stream.
 
841
    */
 
842
    else if (! is_param_long_data_type(param))
 
843
      DBUG_RETURN(1);
812
844
    if (param->convert_str_value(stmt->thd))
813
845
      DBUG_RETURN(1);                           /* out of memory */
814
846
  }
1240
1272
 
1241
1273
  if (mysql_prepare_update(thd, table_list, &select->where,
1242
1274
                           select->order_list.elements,
1243
 
                           (ORDER *) select->order_list.first))
 
1275
                           select->order_list.first))
1244
1276
    goto error;
1245
1277
 
1246
1278
#ifndef NO_EMBEDDED_ACCESS_CHECKS
1343
1375
 
1344
1376
  if (!lex->result && !(lex->result= new (stmt->mem_root) select_send))
1345
1377
  {
1346
 
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(select_send));
 
1378
    my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(select_send)));
1347
1379
    goto error;
1348
1380
  }
1349
1381
 
1350
1382
  if (open_normal_and_derived_tables(thd, tables, 0))
1351
1383
    goto error;
1352
1384
 
1353
 
  thd->used_tables= 0;                        // Updated by setup_fields
 
1385
  thd->lex->used_tables= 0;                        // Updated by setup_fields
1354
1386
 
1355
1387
  /*
1356
1388
    JOIN::prepare calls
1519
1551
  if (specific_prepare && (*specific_prepare)(thd))
1520
1552
    DBUG_RETURN(TRUE);
1521
1553
 
1522
 
  thd->used_tables= 0;                        // Updated by setup_fields
 
1554
  thd->lex->used_tables= 0;                        // Updated by setup_fields
1523
1555
 
1524
1556
  /* Calls JOIN::prepare */
1525
1557
  DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option));
1596
1628
    {
1597
1629
      lex->link_first_table_back(create_table, link_to_local);
1598
1630
      create_table->create= TRUE;
 
1631
      /* Base table and temporary table are not in the same name space. */
 
1632
      create_table->skip_temporary= true;
1599
1633
    }
1600
1634
 
1601
1635
    if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
1654
1688
  if (open_normal_and_derived_tables(thd, tables, 0))
1655
1689
    goto err;
1656
1690
 
1657
 
  lex->view_prepare_mode= 1;
 
1691
  lex->context_analysis_only|=  CONTEXT_ANALYSIS_ONLY_VIEW;
1658
1692
  res= select_like_stmt_test(stmt, 0, 0);
1659
1693
 
1660
1694
err:
1744
1778
static int mysql_insert_select_prepare_tester(THD *thd)
1745
1779
{
1746
1780
  SELECT_LEX *first_select= &thd->lex->select_lex;
1747
 
  TABLE_LIST *second_table= ((TABLE_LIST*)first_select->table_list.first)->
1748
 
    next_local;
 
1781
  TABLE_LIST *second_table= first_select->table_list.first->next_local;
1749
1782
 
1750
1783
  /* Skip first table, which is the table we are inserting in */
1751
 
  first_select->table_list.first= (uchar *) second_table;
 
1784
  first_select->table_list.first= second_table;
1752
1785
  thd->lex->select_lex.context.table_list=
1753
1786
    thd->lex->select_lex.context.first_name_resolution_table= second_table;
1754
1787
 
1785
1818
    return 1;
1786
1819
 
1787
1820
  /* store it, because mysql_insert_select_prepare_tester change it */
1788
 
  first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first;
 
1821
  first_local_table= lex->select_lex.table_list.first;
1789
1822
  DBUG_ASSERT(first_local_table != 0);
1790
1823
 
1791
1824
  res=
1793
1826
                                    &mysql_insert_select_prepare_tester,
1794
1827
                                    OPTION_SETUP_TABLES_DONE);
1795
1828
  /* revert changes  made by mysql_insert_select_prepare_tester */
1796
 
  lex->select_lex.table_list.first= (uchar*) first_local_table;
 
1829
  lex->select_lex.table_list.first= first_local_table;
1797
1830
  return res;
1798
1831
}
1799
1832
 
2201
2234
}
2202
2235
 
2203
2236
 
2204
 
/** Init PS/SP specific parse tree members.  */
2205
 
 
2206
 
static void init_stmt_after_parse(LEX *lex)
2207
 
{
2208
 
  SELECT_LEX *sl= lex->all_selects_list;
2209
 
  /*
2210
 
    Switch off a temporary flag that prevents evaluation of
2211
 
    subqueries in statement prepare.
2212
 
  */
2213
 
  for (; sl; sl= sl->next_select_in_list())
2214
 
   sl->uncacheable&= ~UNCACHEABLE_PREPARE;
2215
 
}
2216
 
 
2217
2237
/**
2218
2238
  SQLCOM_PREPARE implementation.
2219
2239
 
2329
2349
        sl->where= sl->prep_where->copy_andor_structure(thd);
2330
2350
        sl->where->cleanup();
2331
2351
      }
 
2352
      else
 
2353
        sl->where= NULL;
2332
2354
      if (sl->prep_having)
2333
2355
      {
2334
2356
        sl->having= sl->prep_having->copy_andor_structure(thd);
2335
2357
        sl->having->cleanup();
2336
2358
      }
 
2359
      else
 
2360
        sl->having= NULL;
2337
2361
      DBUG_ASSERT(sl->join == 0);
2338
2362
      ORDER *order;
2339
2363
      /* Fix GROUP list */
2340
 
      for (order= (ORDER *)sl->group_list.first; order; order= order->next)
 
2364
      for (order= sl->group_list.first; order; order= order->next)
2341
2365
        order->item= &order->item_ptr;
2342
2366
      /* Fix ORDER list */
2343
 
      for (order= (ORDER *)sl->order_list.first; order; order= order->next)
 
2367
      for (order= sl->order_list.first; order; order= order->next)
2344
2368
        order->item= &order->item_ptr;
2345
2369
 
2346
2370
      /* clear the no_error flag for INSERT/UPDATE IGNORE */
2377
2401
    (multi-delete).  We do a full clean up, although at the moment all we
2378
2402
    need to clean in the tables of MULTI-DELETE list is 'table' member.
2379
2403
  */
2380
 
  for (TABLE_LIST *tables= (TABLE_LIST*) lex->auxiliary_table_list.first;
 
2404
  for (TABLE_LIST *tables= lex->auxiliary_table_list.first;
2381
2405
       tables;
2382
2406
       tables= tables->next_global)
2383
2407
  {
2454
2478
  if (!(stmt= find_prepared_statement(thd, stmt_id)))
2455
2479
  {
2456
2480
    char llbuf[22];
2457
 
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
 
2481
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
2458
2482
             llstr(stmt_id, llbuf), "mysqld_stmt_execute");
2459
2483
    DBUG_VOID_RETURN;
2460
2484
  }
2512
2536
  if (!(stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
2513
2537
  {
2514
2538
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
2515
 
             name->length, name->str, "EXECUTE");
 
2539
             static_cast<int>(name->length), name->str, "EXECUTE");
2516
2540
    DBUG_VOID_RETURN;
2517
2541
  }
2518
2542
 
2554
2578
  if (!(stmt= find_prepared_statement(thd, stmt_id)))
2555
2579
  {
2556
2580
    char llbuf[22];
2557
 
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
 
2581
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
2558
2582
             llstr(stmt_id, llbuf), "mysqld_stmt_fetch");
2559
2583
    DBUG_VOID_RETURN;
2560
2584
  }
2621
2645
  if (!(stmt= find_prepared_statement(thd, stmt_id)))
2622
2646
  {
2623
2647
    char llbuf[22];
2624
 
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf),
 
2648
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)),
2625
2649
             llstr(stmt_id, llbuf), "mysqld_stmt_reset");
2626
2650
    DBUG_VOID_RETURN;
2627
2651
  }
2696
2720
 
2697
2721
  if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name)))
2698
2722
    my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0),
2699
 
             name->length, name->str, "DEALLOCATE PREPARE");
 
2723
             static_cast<int>(name->length), name->str, "DEALLOCATE PREPARE");
2700
2724
  else if (stmt->is_in_use())
2701
2725
    my_error(ER_PS_NO_RECURSION, MYF(0));
2702
2726
  else
2706
2730
  }
2707
2731
}
2708
2732
 
 
2733
 
 
2734
class Set_longdata_error_handler : public Internal_error_handler
 
2735
{
 
2736
public:
 
2737
  Set_longdata_error_handler(Prepared_statement *statement)
 
2738
    : stmt(statement)
 
2739
  { }
 
2740
 
 
2741
public:
 
2742
  bool handle_error(uint sql_errno,
 
2743
                    const char *message,
 
2744
                    MYSQL_ERROR::enum_warning_level level,
 
2745
                    THD *)
 
2746
  {
 
2747
    stmt->state= Query_arena::ERROR;
 
2748
    stmt->last_errno= sql_errno;
 
2749
    strncpy(stmt->last_error, message, MYSQL_ERRMSG_SIZE);
 
2750
 
 
2751
    return TRUE;
 
2752
  }
 
2753
 
 
2754
private:
 
2755
  Prepared_statement *stmt;
 
2756
};
 
2757
 
 
2758
 
2709
2759
/**
2710
2760
  Handle long data in pieces from client.
2711
2761
 
2762
2812
 
2763
2813
  param= stmt->param_array[param_number];
2764
2814
 
 
2815
  Set_longdata_error_handler err_handler(stmt);
 
2816
  /*
 
2817
    Install handler that will catch any errors that can be generated
 
2818
    during execution of Item_param::set_longdata() and propagate
 
2819
    them to Statement::last_error.
 
2820
  */
 
2821
  thd->push_internal_handler(&err_handler);
2765
2822
#ifndef EMBEDDED_LIBRARY
2766
 
  if (param->set_longdata(packet, (ulong) (packet_end - packet)))
 
2823
  param->set_longdata(packet, (ulong) (packet_end - packet));
2767
2824
#else
2768
 
  if (param->set_longdata(thd->extra_data, thd->extra_length))
 
2825
  param->set_longdata(thd->extra_data, thd->extra_length);
2769
2826
#endif
2770
 
  {
2771
 
    stmt->state= Query_arena::ERROR;
2772
 
    stmt->last_errno= ER_OUTOFMEMORY;
2773
 
    sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0);
2774
 
  }
 
2827
  thd->pop_internal_handler();
2775
2828
 
2776
2829
  general_log_print(thd, thd->command, NullS);
2777
2830
 
3032
3085
  old_stmt_arena= thd->stmt_arena;
3033
3086
  thd->stmt_arena= this;
3034
3087
 
3035
 
  Parser_state parser_state(thd, thd->query(), thd->query_length());
 
3088
  Parser_state parser_state;
 
3089
  if (parser_state.init(thd, thd->query(), thd->query_length()))
 
3090
  {
 
3091
    thd->restore_backup_statement(this, &stmt_backup);
 
3092
    thd->restore_active_arena(this, &stmt_backup);
 
3093
    thd->stmt_arena= old_stmt_arena;
 
3094
    DBUG_RETURN(TRUE);
 
3095
  }
 
3096
 
3036
3097
  parser_state.m_lip.stmt_prepare_mode= TRUE;
3037
3098
  lex_start(thd);
 
3099
  lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PREPARE;
3038
3100
 
3039
3101
  error= parse_sql(thd, & parser_state, NULL) ||
3040
 
         thd->is_error() ||
3041
 
         init_param_array(this);
 
3102
    thd->is_error() ||
 
3103
    init_param_array(this);
3042
3104
 
3043
3105
  lex->set_trg_event_type_for_tables();
3044
3106
 
3087
3149
  if (error == 0)
3088
3150
  {
3089
3151
    setup_set_params();
3090
 
    init_stmt_after_parse(lex);
 
3152
    lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
3091
3153
    state= Query_arena::PREPARED;
3092
3154
    flags&= ~ (uint) IS_IN_USE;
3093
3155
    /*
3224
3286
  bool error;
3225
3287
  int reprepare_attempt= 0;
3226
3288
 
 
3289
  /* Check if we got an error when sending long data */
 
3290
  if (state == Query_arena::ERROR)
 
3291
  {
 
3292
    my_message(last_errno, last_error, MYF(0));
 
3293
    return TRUE;
 
3294
  }
 
3295
 
3227
3296
  if (set_parameters(expanded_query, packet, packet_end))
3228
3297
    return TRUE;
3229
3298
 
3464
3533
 
3465
3534
  status_var_increment(thd->status_var.com_stmt_execute);
3466
3535
 
3467
 
  /* Check if we got an error when sending long data */
3468
 
  if (state == Query_arena::ERROR)
3469
 
  {
3470
 
    my_message(last_errno, last_error, MYF(0));
3471
 
    return TRUE;
3472
 
  }
3473
3536
  if (flags & (uint) IS_IN_USE)
3474
3537
  {
3475
3538
    my_error(ER_PS_NO_RECURSION, MYF(0));