Commit f1696d4f authored by unknown's avatar unknown

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
parent ad22d0cb
......@@ -1585,7 +1585,7 @@ fe 00 . .
@node 4.1 protocol changes,,,
@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.
The new things that we support with 4.1 are:
......@@ -1596,7 +1596,7 @@ Warnings
@item
Prepared statements
@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)
@end itemize
......@@ -1617,15 +1617,15 @@ results will sent as binary (low-byte-first).
@end itemize
@node 4.1 field package,,,
@section 4.1 field description package
@node 4.1 field packet,,,
@section 4.1 field description packet
The field description package is sent as a response to a query that
contains a result set. It can be distinguished from a ok package by
the fact that the first byte can't be 0 for a field package.
@xref {4.1 ok package}.
The field description packet is sent as a response to a query that
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 packet.
@xref {4.1 ok packet}.
The header package has the following structure:
The header packet has the following structure:
@multitable @columnfractions .10 .90
@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)
@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}.
@node 4.1 field desc,,,
......@@ -1655,17 +1655,17 @@ The field description result set contains the meta info for a result set.
@end multitable
@node 4.1 ok package,,,
@section 4.1 ok package
@node 4.1 ok packet,,,
@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.
The ok package has the following structure:
The ok packet has the following structure:
@multitable @columnfractions .10 .90
@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 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
......@@ -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.
@node 4.1 end package,,,
@section 4.1 end package
@node 4.1 end packet,,,
@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
@item
......@@ -1695,41 +1695,42 @@ End of parameter type information
End of result set
@end itemize
The end package has the following structure:
The end packet has the following structure:
@multitable @columnfractions .10 .90
@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 Status flags (For flags like SERVER_STATUS_MORE_RESULTS)
@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
by checking the packet length < 9 bytes (in which case it's and end
packet).
@node 4.1 error package
@section 4.1 error package.
@node 4.1 error packet
@section 4.1 error packet.
The error package is sent when something goes wrong.
The error package has the following structure:
The error packet is sent when something goes wrong.
The error packet has the following structure:
@multitable @columnfractions .10 .90
@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
@end multitable
The client/server protocol is designed in such a way that a package
can only start with 255 if it's an error package.
The client/server protocol is designed in such a way that a packet
can only start with 255 if it's an error packet.
@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.
@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
able to provide the optimal information for all parameters.
If number of columns, in the header package, is not 0 then the
prepared statement will contain a result set. In this case the package
If number of columns, in the header packet, is not 0 then the
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}.
......@@ -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
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
has been sent. (Ie; That the last call to mysql_send_long_data() has
the 'last_data' flag set).
This package is sent from client -> server:
This packet is sent from client -> server:
@multitable @columnfractions .10 .90
@item Size @tab Comment
@item 4 @tab Statement handler
@item 2 @tab Parameter number
@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
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
will get the error when calling execute.
......@@ -1791,9 +1792,9 @@ will get the error when calling execute.
@section 4.1 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
@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
@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.
@node 4.1 binary result,,,
......@@ -1836,11 +1837,11 @@ For each result row:
@item
null bit map with first two bits set to 01 (bit 0,1 value 1)
@item
parameter data, repeated for each not null parameter.
parameter data, repeated for each not null result column.
@end itemize
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.
Except that the null-bit-map is shifted two steps, the server is
......
......@@ -1907,12 +1907,9 @@ ha_innobase::write_row(
the counter here. */
skip_auto_inc_decr = FALSE;
if (error == DB_DUPLICATE_KEY) {
ut_a(user_thd->query);
dict_accept(user_thd->query, "REPLACE",
&skip_auto_inc_decr);
}
if (error == DB_DUPLICATE_KEY &&
user_thd->lex.sql_command == SQLCOM_REPLACE)
skip_auto_inc_decr= TRUE;
if (!skip_auto_inc_decr && incremented_auto_inc_counter
&& prebuilt->trx->auto_inc_lock) {
......
......@@ -267,8 +267,6 @@ public:
}
Item_string(const char *name_par,const char *str,uint length)
{
if (!length)
length=strlen(str);
str_value.set(str,length);
max_length=length;
name=(char*) name_par;
......
......@@ -294,10 +294,12 @@ Item *create_func_pow(Item* a, Item *b)
Item *create_func_current_user()
{
THD *thd=current_thd;
Item_string *res=new Item_string("CURRENT_USER()", thd->priv_user, 0);
res->append("@", 1);
res->append((char *)thd->host_or_ip, 0);
return res;
char buff[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
uint length;
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)
......@@ -403,7 +405,7 @@ Item *create_func_ucase(Item* a)
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)
......
......@@ -73,7 +73,7 @@ extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
#include "thr_alarm.h"
#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);
......
......@@ -1870,7 +1870,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
ulong rights, ulong col_rights,
bool revoke_grant)
{
char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH];
char grantor[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
int old_row_exists = 1;
int error=0;
ulong store_table_rights, store_col_rights;
......
......@@ -496,6 +496,7 @@ check_connections(THD *thd)
{
vio_in_addr(net->vio,&thd->remote.sin_addr);
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)
return(ER_HOST_IS_BLOCKED);
}
......@@ -512,6 +513,7 @@ check_connections(THD *thd)
thd->ip=0;
bzero((char*) &thd->remote,sizeof(struct sockaddr));
}
/* Ensure that wrong hostnames doesn't cause buffer overflows */
vio_keepalive(net->vio, TRUE);
ulong pkt_len=0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment