Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
10f5982e
Commit
10f5982e
authored
Mar 15, 2011
by
Dmitry Shulga
Browse files
Options
Browse Files
Download
Plain Diff
Manual merge from mysql-5.1 for Bug#11764168 (56976: Severe denial
of service in prepared statements).
parents
14df359b
6c2f5e30
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
161 additions
and
11 deletions
+161
-11
mysql-test/r/mysqld--help-notwin.result
mysql-test/r/mysqld--help-notwin.result
+5
-0
mysql-test/r/mysqld--help-win.result
mysql-test/r/mysqld--help-win.result
+5
-0
mysql-test/r/variables.result
mysql-test/r/variables.result
+3
-0
mysql-test/suite/sys_vars/r/max_long_data_size_basic.result
mysql-test/suite/sys_vars/r/max_long_data_size_basic.result
+14
-0
mysql-test/suite/sys_vars/t/max_long_data_size_basic.test
mysql-test/suite/sys_vars/t/max_long_data_size_basic.test
+17
-0
mysql-test/t/variables.test
mysql-test/t/variables.test
+5
-0
sql/item.cc
sql/item.cc
+10
-0
sql/mysqld.cc
sql/mysqld.cc
+17
-0
sql/mysqld.h
sql/mysqld.h
+3
-1
sql/sql_prepare.cc
sql/sql_prepare.cc
+21
-10
sql/sys_vars.cc
sql/sys_vars.cc
+10
-0
tests/mysql_client_test.c
tests/mysql_client_test.c
+51
-0
No files found.
mysql-test/r/mysqld--help-notwin.result
View file @
10f5982e
...
...
@@ -309,6 +309,10 @@ The following options may be given as the first argument:
max_join_size records return an error
--max-length-for-sort-data=#
Max number of bytes in sorted records
--max-long-data-size=#
The maximum BLOB length to send to server from
mysql_send_long_data API. Deprecated option; use
max_allowed_packet instead.
--max-prepared-stmt-count=#
Maximum number of prepared statements in the server
--max-relay-log-size=#
...
...
@@ -830,6 +834,7 @@ max-error-count 64
max-heap-table-size 16777216
max-join-size 18446744073709551615
max-length-for-sort-data 1024
max-long-data-size 1048576
max-prepared-stmt-count 16382
max-relay-log-size 0
max-seeks-for-key 18446744073709551615
...
...
mysql-test/r/mysqld--help-win.result
View file @
10f5982e
...
...
@@ -308,6 +308,10 @@ The following options may be given as the first argument:
max_join_size records return an error
--max-length-for-sort-data=#
Max number of bytes in sorted records
--max-long-data-size=#
The maximum BLOB length to send to server from
mysql_send_long_data API. Deprecated option; use
max_allowed_packet instead.
--max-prepared-stmt-count=#
Maximum number of prepared statements in the server
--max-relay-log-size=#
...
...
@@ -833,6 +837,7 @@ max-error-count 64
max-heap-table-size 16777216
max-join-size 18446744073709551615
max-length-for-sort-data 1024
max-long-data-size 1048576
max-prepared-stmt-count 16382
max-relay-log-size 0
max-seeks-for-key 18446744073709551615
...
...
mysql-test/r/variables.result
View file @
10f5982e
...
...
@@ -1540,6 +1540,9 @@ ERROR HY000: Cannot drop default keycache
SET @@global.key_cache_block_size=0;
Warnings:
Warning 1292 Truncated incorrect key_cache_block_size value: '0'
select @@max_long_data_size;
@@max_long_data_size
1048576
SET @@global.max_binlog_cache_size=DEFAULT;
SET @@global.max_join_size=DEFAULT;
SET @@global.key_buffer_size=@kbs;
...
...
mysql-test/suite/sys_vars/r/max_long_data_size_basic.result
0 → 100644
View file @
10f5982e
select @@global.max_long_data_size=20;
@@global.max_long_data_size=20
0
select @@session.max_long_data_size;
ERROR HY000: Variable 'max_long_data_size' is a GLOBAL variable
SELECT @@global.max_long_data_size = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='max_long_data_size';
@@global.max_long_data_size = VARIABLE_VALUE
1
set global max_long_data_size=1;
ERROR HY000: Variable 'max_long_data_size' is a read only variable
set session max_long_data_size=1;
ERROR HY000: Variable 'max_long_data_size' is a read only variable
mysql-test/suite/sys_vars/t/max_long_data_size_basic.test
0 → 100644
View file @
10f5982e
select
@@
global
.
max_long_data_size
=
20
;
--
error
ER_INCORRECT_GLOBAL_LOCAL_VAR
select
@@
session
.
max_long_data_size
;
# Show that value of the variable matches the value in the GLOBAL I_S table
SELECT
@@
global
.
max_long_data_size
=
VARIABLE_VALUE
FROM
INFORMATION_SCHEMA
.
GLOBAL_VARIABLES
WHERE
VARIABLE_NAME
=
'max_long_data_size'
;
#
# show that it's read-only
#
--
error
ER_INCORRECT_GLOBAL_LOCAL_VAR
set
global
max_long_data_size
=
1
;
--
error
ER_INCORRECT_GLOBAL_LOCAL_VAR
set
session
max_long_data_size
=
1
;
mysql-test/t/variables.test
View file @
10f5982e
...
...
@@ -1281,6 +1281,11 @@ SET @@global.max_join_size=0;
SET
@@
global
.
key_buffer_size
=
0
;
SET
@@
global
.
key_cache_block_size
=
0
;
#
# Bug#56976: added new start-up parameter
#
select
@@
max_long_data_size
;
# cleanup
SET
@@
global
.
max_binlog_cache_size
=
DEFAULT
;
SET
@@
global
.
max_join_size
=
DEFAULT
;
...
...
sql/item.cc
View file @
10f5982e
...
...
@@ -2885,6 +2885,16 @@ bool Item_param::set_longdata(const char *str, ulong length)
(here), and first have to concatenate all pieces together,
write query to the binary log and only then perform conversion.
*/
if
(
str_value
.
length
()
+
length
>
max_long_data_size
)
{
my_message
(
ER_UNKNOWN_ERROR
,
"Parameter of prepared statement which is set through "
"mysql_send_long_data() is longer than "
"'max_long_data_size' bytes"
,
MYF
(
0
));
DBUG_RETURN
(
true
);
}
if
(
str_value
.
append
(
str
,
length
,
&
my_charset_bin
))
DBUG_RETURN
(
TRUE
);
state
=
LONG_DATA_VALUE
;
...
...
sql/mysqld.cc
View file @
10f5982e
...
...
@@ -324,6 +324,7 @@ static PSI_rwlock_key key_rwlock_openssl;
/* the default log output is log tables */
static
bool
lower_case_table_names_used
=
0
;
static
bool
max_long_data_size_used
=
false
;
static
bool
volatile
select_thread_in_use
,
signal_thread_in_use
;
/* See Bug#56666 and Bug#56760 */
;
volatile
bool
ready_to_exit
;
...
...
@@ -478,6 +479,11 @@ ulong specialflag=0;
ulong
binlog_cache_use
=
0
,
binlog_cache_disk_use
=
0
;
ulong
binlog_stmt_cache_use
=
0
,
binlog_stmt_cache_disk_use
=
0
;
ulong
max_connections
,
max_connect_errors
;
/*
Maximum length of parameter value which can be set through
mysql_send_long_data() call.
*/
ulong
max_long_data_size
;
/**
Limit of the total number of prepared statements in the server.
Is necessary to protect the server against out-of-memory attacks.
...
...
@@ -7160,6 +7166,10 @@ mysqld_get_one_option(int optid,
if
(
argument
==
NULL
)
/* no argument */
log_error_file_ptr
=
const_cast
<
char
*>
(
""
);
break
;
case
OPT_MAX_LONG_DATA_SIZE
:
max_long_data_size_used
=
true
;
WARN_DEPRECATED
(
NULL
,
5
,
6
,
"--max_long_data_size"
,
"'--max_allowed_packet'"
);
break
;
}
return
0
;
}
...
...
@@ -7386,6 +7396,13 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
opt_readonly
=
read_only
;
/*
If max_long_data_size is not specified explicitly use
value of max_allowed_packet.
*/
if
(
!
max_long_data_size_used
)
max_long_data_size
=
global_system_variables
.
max_allowed_packet
;
return
0
;
}
...
...
sql/mysqld.h
View file @
10f5982e
...
...
@@ -126,6 +126,7 @@ extern char *default_storage_engine;
extern
bool
opt_endinfo
,
using_udf_functions
;
extern
my_bool
locked_in_memory
;
extern
bool
opt_using_transactions
;
extern
ulong
max_long_data_size
;
extern
ulong
current_pid
;
extern
ulong
expire_logs_days
;
extern
my_bool
relay_log_recovery
;
...
...
@@ -397,7 +398,8 @@ enum options_mysqld
OPT_UPDATE_LOG
,
OPT_WANT_CORE
,
OPT_ENGINE_CONDITION_PUSHDOWN
,
OPT_LOG_ERROR
OPT_LOG_ERROR
,
OPT_MAX_LONG_DATA_SIZE
};
...
...
sql/sql_prepare.cc
View file @
10f5982e
...
...
@@ -2784,6 +2784,7 @@ void mysql_sql_stmt_close(THD *thd)
}
}
/**
Handle long data in pieces from client.
...
...
@@ -2840,16 +2841,25 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
param
=
stmt
->
param_array
[
param_number
];
Diagnostics_area
new_stmt_da
,
*
save_stmt_da
=
thd
->
stmt_da
;
Warning_info
new_warnning_info
(
thd
->
query_id
),
*
save_warinig_info
=
thd
->
warning_info
;
thd
->
stmt_da
=
&
new_stmt_da
;
thd
->
warning_info
=
&
new_warnning_info
;
#ifndef EMBEDDED_LIBRARY
if
(
param
->
set_longdata
(
packet
,
(
ulong
)
(
packet_end
-
packet
)))
param
->
set_longdata
(
packet
,
(
ulong
)
(
packet_end
-
packet
));
#else
if
(
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
))
param
->
set_longdata
(
thd
->
extra_data
,
thd
->
extra_length
);
#endif
if
(
thd
->
stmt_da
->
is_error
())
{
stmt
->
state
=
Query_arena
::
ERROR
;
stmt
->
last_errno
=
ER_OUTOFMEMORY
;
s
printf
(
stmt
->
last_error
,
ER
(
ER_OUTOFMEMORY
),
0
);
stmt
->
last_errno
=
thd
->
stmt_da
->
sql_errno
()
;
s
trncpy
(
stmt
->
last_error
,
thd
->
stmt_da
->
message
(),
MYSQL_ERRMSG_SIZE
);
}
thd
->
stmt_da
=
save_stmt_da
;
thd
->
warning_info
=
save_warinig_info
;
general_log_print
(
thd
,
thd
->
command
,
NullS
);
...
...
@@ -3389,6 +3399,13 @@ Prepared_statement::execute_loop(String *expanded_query,
bool
error
;
int
reprepare_attempt
=
0
;
/* Check if we got an error when sending long data */
if
(
state
==
Query_arena
::
ERROR
)
{
my_message
(
last_errno
,
last_error
,
MYF
(
0
));
return
TRUE
;
}
if
(
set_parameters
(
expanded_query
,
packet
,
packet_end
))
return
TRUE
;
...
...
@@ -3656,12 +3673,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
status_var_increment
(
thd
->
status_var
.
com_stmt_execute
);
/* Check if we got an error when sending long data */
if
(
state
==
Query_arena
::
ERROR
)
{
my_message
(
last_errno
,
last_error
,
MYF
(
0
));
return
TRUE
;
}
if
(
flags
&
(
uint
)
IS_IN_USE
)
{
my_error
(
ER_PS_NO_RECURSION
,
MYF
(
0
));
...
...
sql/sys_vars.cc
View file @
10f5982e
...
...
@@ -1182,6 +1182,16 @@ static Sys_var_harows Sys_sql_max_join_size(
NO_MUTEX_GUARD
,
NOT_IN_BINLOG
,
ON_CHECK
(
0
),
ON_UPDATE
(
fix_max_join_size
),
DEPRECATED
(
70000
,
0
));
static
Sys_var_ulong
Sys_max_long_data_size
(
"max_long_data_size"
,
"The maximum BLOB length to send to server from "
"mysql_send_long_data API. Deprecated option; "
"use max_allowed_packet instead."
,
READ_ONLY
GLOBAL_VAR
(
max_long_data_size
),
CMD_LINE
(
REQUIRED_ARG
,
OPT_MAX_LONG_DATA_SIZE
),
VALID_RANGE
(
1024
,
UINT_MAX32
),
DEFAULT
(
1024
*
1024
),
BLOCK_SIZE
(
1
));
static
PolyLock_mutex
PLock_prepared_stmt_count
(
&
LOCK_prepared_stmt_count
);
static
Sys_var_ulong
Sys_max_prepared_stmt_count
(
"max_prepared_stmt_count"
,
...
...
tests/mysql_client_test.c
View file @
10f5982e
...
...
@@ -19464,6 +19464,56 @@ static void test_bug49972()
}
/*
Bug #56976: Severe Denial Of Service in prepared statements
*/
static
void
test_bug56976
()
{
MYSQL_STMT
*
stmt
;
MYSQL_BIND
bind
[
1
];
int
rc
;
const
char
*
query
=
"SELECT LENGTH(?)"
;
char
*
long_buffer
;
unsigned
long
i
,
packet_len
=
256
*
1024L
;
unsigned
long
dos_len
=
2
*
1024
*
1024L
;
DBUG_ENTER
(
"test_bug56976"
);
myheader
(
"test_bug56976"
);
stmt
=
mysql_stmt_init
(
mysql
);
check_stmt
(
stmt
);
rc
=
mysql_stmt_prepare
(
stmt
,
query
,
strlen
(
query
));
check_execute
(
stmt
,
rc
);
memset
(
bind
,
0
,
sizeof
(
bind
));
bind
[
0
].
buffer_type
=
MYSQL_TYPE_TINY_BLOB
;
rc
=
mysql_stmt_bind_param
(
stmt
,
bind
);
check_execute
(
stmt
,
rc
);
long_buffer
=
(
char
*
)
my_malloc
(
packet_len
,
MYF
(
0
));
DIE_UNLESS
(
long_buffer
);
memset
(
long_buffer
,
'a'
,
packet_len
);
for
(
i
=
0
;
i
<
dos_len
/
packet_len
;
i
++
)
{
rc
=
mysql_stmt_send_long_data
(
stmt
,
0
,
long_buffer
,
packet_len
);
check_execute
(
stmt
,
rc
);
}
my_free
(
long_buffer
);
rc
=
mysql_stmt_execute
(
stmt
);
DIE_UNLESS
(
rc
&&
mysql_stmt_errno
(
stmt
)
==
ER_UNKNOWN_ERROR
);
mysql_stmt_close
(
stmt
);
DBUG_VOID_RETURN
;
}
/**
Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
*/
...
...
@@ -19838,6 +19888,7 @@ static struct my_tests_st my_tests[]= {
{
"test_bug47485"
,
test_bug47485
},
{
"test_bug58036"
,
test_bug58036
},
{
"test_bug57058"
,
test_bug57058
},
{
"test_bug56976"
,
test_bug56976
},
{
0
,
0
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment