Fix out-of-bounds reads with LOAD DATA LOCAL INFILE

When a LOAD DATA LOCAL INFILE is done, the last packet is an empty packet
which does not contain the command byte. Some parts of the MySQL protocol
modules expected that a command is always present. The proper way to
handle this is to use the mxs_mysql_get_command function which does bounds
checking.
This commit is contained in:
Markus Mäkelä
2017-08-17 21:37:11 +03:00
parent d723201d22
commit 6c5ae24dff
2 changed files with 4 additions and 6 deletions

View File

@ -386,7 +386,7 @@ static inline void prepare_for_write(DCB *dcb, GWBUF *buffer)
if (GWBUF_IS_TYPE_SESCMD(buffer))
{
mysql_server_cmd_t cmd = MYSQL_GET_COMMAND(GWBUF_DATA(buffer));
mysql_server_cmd_t cmd = mxs_mysql_get_command(buffer);
protocol_add_srv_command(proto, cmd);
}
if (GWBUF_SHOULD_COLLECT_RESULT(buffer))
@ -1015,7 +1015,7 @@ static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
case MXS_AUTH_STATE_COMPLETE:
{
uint8_t* ptr = GWBUF_DATA(queue);
mysql_server_cmd_t cmd = MYSQL_GET_COMMAND(ptr);
mysql_server_cmd_t cmd = mxs_mysql_get_command(queue);
MXS_DEBUG("write to dcb %p fd %d protocol state %s.",
dcb, dcb->fd, STRPROTOCOLSTATE(backend_protocol->protocol_auth_state));

View File

@ -1443,7 +1443,7 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
CHK_GWBUF(packetbuf);
MySQLProtocol* proto = (MySQLProtocol*)session->client_dcb->protocol;
proto->current_command = (mysql_server_cmd_t)GWBUF_DATA(packetbuf)[4];
proto->current_command = (mysql_server_cmd_t)mxs_mysql_get_command(packetbuf);
/**
* This means that buffer includes exactly one MySQL
@ -1480,14 +1480,12 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
if (rcap_type_required(capabilities, RCAP_TYPE_TRANSACTION_TRACKING))
{
uint8_t *data = GWBUF_DATA(packetbuf);
if (session_trx_is_ending(session))
{
session_set_trx_state(session, SESSION_TRX_INACTIVE);
}
if (MYSQL_GET_COMMAND(data) == MYSQL_COM_QUERY)
if (mxs_mysql_get_command(packetbuf) == MYSQL_COM_QUERY)
{
uint32_t type = qc_get_trx_type_mask(packetbuf);