mirror of
https://github.com/MariaDB/server.git
synced 2026-04-23 16:55:31 +02:00
Cut hostnames at HOSTNAME_LENGTH to avoid theoretical hostname overruns
Changed long packat handling to check for packets of length 0xffffff. This does however break packet handling for older clients. If you are using packets >= 16M then you need to upgrade client and server after this patch. Docs/internals.texi: Updated documentation for 4.1 protocol sql/ha_innodb.cc: Optimization of checking command sql/item.h: Removed automatic set of length for Item_string sql/item_create.cc: Optimized create of create_func_current_user() sql/net_serv.cc: Fixed wrong max packet length sql/sql_acl.cc: Safety fix. sql/sql_parse.cc: Cut hostnames at HOSTNAME_LENGTH to avoid theoretical hostname overruns
This commit is contained in:
parent
ad22d0cbac
commit
f1696d4f5f
7 changed files with 56 additions and 56 deletions
|
|
@ -1585,7 +1585,7 @@ fe 00 . .
|
||||||
@node 4.1 protocol changes,,,
|
@node 4.1 protocol changes,,,
|
||||||
@section Changes to 4.0 protocol in 4.1
|
@section Changes to 4.0 protocol in 4.1
|
||||||
|
|
||||||
All basic package handling is identical to 4.0. When communication
|
All basic packet handling is identical to 4.0. When communication
|
||||||
with an old 4.0 or 3.x client we will use the old protocol.
|
with an old 4.0 or 3.x client we will use the old protocol.
|
||||||
|
|
||||||
The new things that we support with 4.1 are:
|
The new things that we support with 4.1 are:
|
||||||
|
|
@ -1596,7 +1596,7 @@ Warnings
|
||||||
@item
|
@item
|
||||||
Prepared statements
|
Prepared statements
|
||||||
@item
|
@item
|
||||||
Binary protocol (will be much faster than the current protocol that
|
Binary protocol (will be faster than the current protocol that
|
||||||
converts everything to strings)
|
converts everything to strings)
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
|
@ -1617,15 +1617,15 @@ results will sent as binary (low-byte-first).
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
@node 4.1 field package,,,
|
@node 4.1 field packet,,,
|
||||||
@section 4.1 field description package
|
@section 4.1 field description packet
|
||||||
|
|
||||||
The field description package is sent as a response to a query that
|
The field description packet is sent as a response to a query that
|
||||||
contains a result set. It can be distinguished from a ok package by
|
contains a result set. It can be distinguished from a ok packet by
|
||||||
the fact that the first byte can't be 0 for a field package.
|
the fact that the first byte can't be 0 for a field packet.
|
||||||
@xref {4.1 ok package}.
|
@xref {4.1 ok packet}.
|
||||||
|
|
||||||
The header package has the following structure:
|
The header packet has the following structure:
|
||||||
|
|
||||||
@multitable @columnfractions .10 .90
|
@multitable @columnfractions .10 .90
|
||||||
@item Size @tab Comment
|
@item Size @tab Comment
|
||||||
|
|
@ -1634,7 +1634,7 @@ The header package has the following structure:
|
||||||
uses this to send the number of rows in the table)
|
uses this to send the number of rows in the table)
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
This package is always followed by a field description set.
|
This packet is always followed by a field description set.
|
||||||
@xref{4.1 field desc}.
|
@xref{4.1 field desc}.
|
||||||
|
|
||||||
@node 4.1 field desc,,,
|
@node 4.1 field desc,,,
|
||||||
|
|
@ -1655,17 +1655,17 @@ The field description result set contains the meta info for a result set.
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
|
|
||||||
@node 4.1 ok package,,,
|
@node 4.1 ok packet,,,
|
||||||
@section 4.1 ok package
|
@section 4.1 ok packet
|
||||||
|
|
||||||
The ok package is the first that is sent as an response for a query
|
The ok packet is the first that is sent as an response for a query
|
||||||
that didn't return a result set.
|
that didn't return a result set.
|
||||||
|
|
||||||
The ok package has the following structure:
|
The ok packet has the following structure:
|
||||||
|
|
||||||
@multitable @columnfractions .10 .90
|
@multitable @columnfractions .10 .90
|
||||||
@item Size @tab Comment
|
@item Size @tab Comment
|
||||||
@item 1 @tab 0 ; Marker for ok package
|
@item 1 @tab 0 ; Marker for ok packet
|
||||||
@item 1-9 @tab Affected rows
|
@item 1-9 @tab Affected rows
|
||||||
@item 1-9 @tab Last insert id (0 if one wasn't used)
|
@item 1-9 @tab Last insert id (0 if one wasn't used)
|
||||||
@item 2 @tab Server status; Can be used by client to check if we are inside an transaction
|
@item 2 @tab Server status; Can be used by client to check if we are inside an transaction
|
||||||
|
|
@ -1681,10 +1681,10 @@ The message is optional. For example for multi line INSERT it
|
||||||
contains a string for how many rows was inserted / deleted.
|
contains a string for how many rows was inserted / deleted.
|
||||||
|
|
||||||
|
|
||||||
@node 4.1 end package,,,
|
@node 4.1 end packet,,,
|
||||||
@section 4.1 end package
|
@section 4.1 end packet
|
||||||
|
|
||||||
The end package is sent as the last package for
|
The end packet is sent as the last packet for
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
|
@ -1695,41 +1695,42 @@ End of parameter type information
|
||||||
End of result set
|
End of result set
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
The end package has the following structure:
|
The end packet has the following structure:
|
||||||
|
|
||||||
@multitable @columnfractions .10 .90
|
@multitable @columnfractions .10 .90
|
||||||
@item Size @tab Comment
|
@item Size @tab Comment
|
||||||
@item 1 @tab 254 ; Marker for EOF package
|
@item 1 @tab 254 ; Marker for EOF packet
|
||||||
@item 2 @tab Warning count
|
@item 2 @tab Warning count
|
||||||
@item 2 @tab Status flags (For flags like SERVER_STATUS_MORE_RESULTS)
|
@item 2 @tab Status flags (For flags like SERVER_STATUS_MORE_RESULTS)
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
Note that a normal package may start with byte 254, which means
|
Note that a normal packet may start with byte 254, which means
|
||||||
'length stored in 9 bytes'. One can different between these cases
|
'length stored in 9 bytes'. One can different between these cases
|
||||||
by checking the packet length < 9 bytes (in which case it's and end
|
by checking the packet length < 9 bytes (in which case it's and end
|
||||||
packet).
|
packet).
|
||||||
|
|
||||||
|
|
||||||
@node 4.1 error package
|
@node 4.1 error packet
|
||||||
@section 4.1 error package.
|
@section 4.1 error packet.
|
||||||
|
|
||||||
The error package is sent when something goes wrong.
|
The error packet is sent when something goes wrong.
|
||||||
The error package has the following structure:
|
The error packet has the following structure:
|
||||||
|
|
||||||
@multitable @columnfractions .10 .90
|
@multitable @columnfractions .10 .90
|
||||||
@item Size @tab Comment
|
@item Size @tab Comment
|
||||||
@item 1 @tab 255 Error package marker
|
@item 1 @tab 255 Error packet marker
|
||||||
|
@item 2 @tab Error code
|
||||||
@item 1-255 @tab Null terminated error message
|
@item 1-255 @tab Null terminated error message
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
The client/server protocol is designed in such a way that a package
|
The client/server protocol is designed in such a way that a packet
|
||||||
can only start with 255 if it's an error package.
|
can only start with 255 if it's an error packet.
|
||||||
|
|
||||||
|
|
||||||
@node 4.1 prep init,,,
|
@node 4.1 prep init,,,
|
||||||
@section 4.1 prepared statement init package
|
@section 4.1 prepared statement init packet
|
||||||
|
|
||||||
This is the return package when one sends a query with the COM_PREPARE
|
This is the return packet when one sends a query with the COM_PREPARE
|
||||||
command.
|
command.
|
||||||
|
|
||||||
@multitable @columnfractions .10 .90
|
@multitable @columnfractions .10 .90
|
||||||
|
|
@ -1755,8 +1756,8 @@ Note that the above is not yet in 4.1 but will be added this month.
|
||||||
As MySQL can have a parameter 'anywhere' it will in many cases not be
|
As MySQL can have a parameter 'anywhere' it will in many cases not be
|
||||||
able to provide the optimal information for all parameters.
|
able to provide the optimal information for all parameters.
|
||||||
|
|
||||||
If number of columns, in the header package, is not 0 then the
|
If number of columns, in the header packet, is not 0 then the
|
||||||
prepared statement will contain a result set. In this case the package
|
prepared statement will contain a result set. In this case the packet
|
||||||
is followed by a field description result set. @xref{4.1 field descr}.
|
is followed by a field description result set. @xref{4.1 field descr}.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1768,22 +1769,22 @@ value. One can call mysql_send_long_data() multiple times for the
|
||||||
same parameter; The server will concatenate the results to a one big
|
same parameter; The server will concatenate the results to a one big
|
||||||
string.
|
string.
|
||||||
|
|
||||||
The server will not require an end package for the string.
|
The server will not require an end packet for the string.
|
||||||
mysql_send_long_data() is responsible updating a flag that all data
|
mysql_send_long_data() is responsible updating a flag that all data
|
||||||
has been sent. (Ie; That the last call to mysql_send_long_data() has
|
has been sent. (Ie; That the last call to mysql_send_long_data() has
|
||||||
the 'last_data' flag set).
|
the 'last_data' flag set).
|
||||||
|
|
||||||
This package is sent from client -> server:
|
This packet is sent from client -> server:
|
||||||
|
|
||||||
@multitable @columnfractions .10 .90
|
@multitable @columnfractions .10 .90
|
||||||
@item Size @tab Comment
|
@item Size @tab Comment
|
||||||
@item 4 @tab Statement handler
|
@item 4 @tab Statement handler
|
||||||
@item 2 @tab Parameter number
|
@item 2 @tab Parameter number
|
||||||
@item 2 @tab Type of parameter (not used at this point)
|
@item 2 @tab Type of parameter (not used at this point)
|
||||||
@item # @tab data (Rest of package)
|
@item # @tab data (Rest of packet)
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
The server will NOT send an @code{ok} or @code{error} package in
|
The server will NOT send an @code{ok} or @code{error} packet in
|
||||||
responce for this. If there is any errors (like to big string), one
|
responce for this. If there is any errors (like to big string), one
|
||||||
will get the error when calling execute.
|
will get the error when calling execute.
|
||||||
|
|
||||||
|
|
@ -1791,9 +1792,9 @@ will get the error when calling execute.
|
||||||
@section 4.1 execute
|
@section 4.1 execute
|
||||||
|
|
||||||
On execute we send all parameters to the server in a COM_EXECUTE
|
On execute we send all parameters to the server in a COM_EXECUTE
|
||||||
package.
|
packet.
|
||||||
|
|
||||||
The package contains the following information:
|
The packet contains the following information:
|
||||||
|
|
||||||
@multitable @columnfractions .30 .70
|
@multitable @columnfractions .30 .70
|
||||||
@item Size @tab Comment
|
@item Size @tab Comment
|
||||||
|
|
@ -1822,7 +1823,7 @@ The parameters are stored the following ways:
|
||||||
@item string @tab 1-9 + # @tab Packed string length + string
|
@item string @tab 1-9 + # @tab Packed string length + string
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
The result for this will be either an ok package or a binary result
|
The result for this will be either an ok packet or a binary result
|
||||||
set.
|
set.
|
||||||
|
|
||||||
@node 4.1 binary result,,,
|
@node 4.1 binary result,,,
|
||||||
|
|
@ -1836,11 +1837,11 @@ For each result row:
|
||||||
@item
|
@item
|
||||||
null bit map with first two bits set to 01 (bit 0,1 value 1)
|
null bit map with first two bits set to 01 (bit 0,1 value 1)
|
||||||
@item
|
@item
|
||||||
parameter data, repeated for each not null parameter.
|
parameter data, repeated for each not null result column.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
The idea with the reserving two bits in the null map is that we can
|
The idea with the reserving two bits in the null map is that we can
|
||||||
use standard error (first byte 255) and ok packages (first byte 0)
|
use standard error (first byte 255) and ok packets (first byte 0)
|
||||||
to end a result sets.
|
to end a result sets.
|
||||||
|
|
||||||
Except that the null-bit-map is shifted two steps, the server is
|
Except that the null-bit-map is shifted two steps, the server is
|
||||||
|
|
|
||||||
|
|
@ -1907,12 +1907,9 @@ ha_innobase::write_row(
|
||||||
the counter here. */
|
the counter here. */
|
||||||
|
|
||||||
skip_auto_inc_decr = FALSE;
|
skip_auto_inc_decr = FALSE;
|
||||||
|
if (error == DB_DUPLICATE_KEY &&
|
||||||
if (error == DB_DUPLICATE_KEY) {
|
user_thd->lex.sql_command == SQLCOM_REPLACE)
|
||||||
ut_a(user_thd->query);
|
skip_auto_inc_decr= TRUE;
|
||||||
dict_accept(user_thd->query, "REPLACE",
|
|
||||||
&skip_auto_inc_decr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!skip_auto_inc_decr && incremented_auto_inc_counter
|
if (!skip_auto_inc_decr && incremented_auto_inc_counter
|
||||||
&& prebuilt->trx->auto_inc_lock) {
|
&& prebuilt->trx->auto_inc_lock) {
|
||||||
|
|
|
||||||
|
|
@ -267,8 +267,6 @@ public:
|
||||||
}
|
}
|
||||||
Item_string(const char *name_par,const char *str,uint length)
|
Item_string(const char *name_par,const char *str,uint length)
|
||||||
{
|
{
|
||||||
if (!length)
|
|
||||||
length=strlen(str);
|
|
||||||
str_value.set(str,length);
|
str_value.set(str,length);
|
||||||
max_length=length;
|
max_length=length;
|
||||||
name=(char*) name_par;
|
name=(char*) name_par;
|
||||||
|
|
|
||||||
|
|
@ -294,10 +294,12 @@ Item *create_func_pow(Item* a, Item *b)
|
||||||
Item *create_func_current_user()
|
Item *create_func_current_user()
|
||||||
{
|
{
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
Item_string *res=new Item_string("CURRENT_USER()", thd->priv_user, 0);
|
char buff[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
|
||||||
res->append("@", 1);
|
uint length;
|
||||||
res->append((char *)thd->host_or_ip, 0);
|
|
||||||
return res;
|
length= (uint) (strxmov(buff, thd->priv_user, "@", thd->host_or_ip, NullS) -
|
||||||
|
buff);
|
||||||
|
return new Item_string("CURRENT_USER()", thd->memdup(buff, length), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *create_func_quarter(Item* a)
|
Item *create_func_quarter(Item* a)
|
||||||
|
|
@ -403,7 +405,7 @@ Item *create_func_ucase(Item* a)
|
||||||
|
|
||||||
Item *create_func_version(void)
|
Item *create_func_version(void)
|
||||||
{
|
{
|
||||||
return new Item_string("VERSION()",server_version, 0);
|
return new Item_string("VERSION()",server_version, strlen(server_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *create_func_weekday(Item* a)
|
Item *create_func_weekday(Item* a)
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
|
||||||
#include "thr_alarm.h"
|
#include "thr_alarm.h"
|
||||||
|
|
||||||
#define TEST_BLOCKING 8
|
#define TEST_BLOCKING 8
|
||||||
#define MAX_THREE_BYTES 255L*255L*255L
|
#define MAX_THREE_BYTES (256L*256L*256L-1)
|
||||||
|
|
||||||
static int net_write_buff(NET *net,const char *packet,ulong len);
|
static int net_write_buff(NET *net,const char *packet,ulong len);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1870,7 +1870,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||||
ulong rights, ulong col_rights,
|
ulong rights, ulong col_rights,
|
||||||
bool revoke_grant)
|
bool revoke_grant)
|
||||||
{
|
{
|
||||||
char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH];
|
char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
|
||||||
int old_row_exists = 1;
|
int old_row_exists = 1;
|
||||||
int error=0;
|
int error=0;
|
||||||
ulong store_table_rights, store_col_rights;
|
ulong store_table_rights, store_col_rights;
|
||||||
|
|
|
||||||
|
|
@ -496,6 +496,7 @@ check_connections(THD *thd)
|
||||||
{
|
{
|
||||||
vio_in_addr(net->vio,&thd->remote.sin_addr);
|
vio_in_addr(net->vio,&thd->remote.sin_addr);
|
||||||
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
|
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
|
||||||
|
thd->host[strnlen(thd->host, HOSTNAME_LENGTH)]= 0;
|
||||||
if (connect_errors > max_connect_errors)
|
if (connect_errors > max_connect_errors)
|
||||||
return(ER_HOST_IS_BLOCKED);
|
return(ER_HOST_IS_BLOCKED);
|
||||||
}
|
}
|
||||||
|
|
@ -512,6 +513,7 @@ check_connections(THD *thd)
|
||||||
thd->ip=0;
|
thd->ip=0;
|
||||||
bzero((char*) &thd->remote,sizeof(struct sockaddr));
|
bzero((char*) &thd->remote,sizeof(struct sockaddr));
|
||||||
}
|
}
|
||||||
|
/* Ensure that wrong hostnames doesn't cause buffer overflows */
|
||||||
vio_keepalive(net->vio, TRUE);
|
vio_keepalive(net->vio, TRUE);
|
||||||
|
|
||||||
ulong pkt_len=0;
|
ulong pkt_len=0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue