qc_sqlite: Protect against misuse

- Ensure contiguous buffer of expected size.
- Ensure COM_QUERY content.
This commit is contained in:
Johan Wikman
2016-10-25 17:59:46 +03:00
parent 46c2b6e76a
commit 8f8823dc41
2 changed files with 52 additions and 27 deletions

View File

@ -433,18 +433,24 @@ static bool parse_query(GWBUF* query)
bool parsed = false; bool parsed = false;
ss_dassert(!query_is_parsed(query)); ss_dassert(!query_is_parsed(query));
if (GWBUF_IS_CONTIGUOUS(query))
{
uint8_t* data = (uint8_t*) GWBUF_DATA(query);
if ((GWBUF_LENGTH(query) >= MYSQL_HEADER_LEN + 1) &&
(GWBUF_LENGTH(query) == MYSQL_HEADER_LEN + MYSQL_GET_PACKET_LEN(data)))
{
if (MYSQL_GET_COMMAND(data) == MYSQL_COM_QUERY)
{
QC_SQLITE_INFO* info = info_alloc(); QC_SQLITE_INFO* info = info_alloc();
if (info) if (info)
{ {
this_thread.info = info; this_thread.info = info;
// TODO: Somewhere it needs to be ensured that this buffer is contiguous.
// TODO: Where is it checked that the GWBUF really contains a query?
uint8_t* data = (uint8_t*) GWBUF_DATA(query);
size_t len = MYSQL_GET_PACKET_LEN(data) - 1; // Subtract 1 for packet type byte. size_t len = MYSQL_GET_PACKET_LEN(data) - 1; // Subtract 1 for packet type byte.
const char* s = (const char*) &data[5]; // TODO: Are there symbolic constants somewhere? const char* s = (const char*) &data[MYSQL_HEADER_LEN + 1];
this_thread.info->query = s; this_thread.info->query = s;
this_thread.info->query_len = len; this_thread.info->query_len = len;
@ -464,6 +470,24 @@ static bool parse_query(GWBUF* query)
{ {
MXS_ERROR("qc_sqlite: Could not allocate structure for containing parse data."); MXS_ERROR("qc_sqlite: Could not allocate structure for containing parse data.");
} }
}
else
{
MXS_ERROR("qc_sqlite: The provided buffer does not contain a COM_QUERY, but a %s.",
STRPACKETTYPE(MYSQL_GET_COMMAND(data)));
}
}
else
{
MXS_ERROR("qc_sqlite: Packet size %ld, provided buffer is %ld.",
MYSQL_HEADER_LEN + MYSQL_GET_PACKET_LEN(data),
GWBUF_LENGTH(query));
}
}
else
{
MXS_ERROR("qc_sqlite: Provided buffer is not contiguous.");
}
return parsed; return parsed;
} }

View File

@ -117,17 +117,18 @@ ostream& operator << (ostream& out, qc_parse_result_t x)
GWBUF* create_gwbuf(const string& s) GWBUF* create_gwbuf(const string& s)
{ {
size_t len = s.length() + 1; size_t len = s.length();
size_t gwbuf_len = len + MYSQL_HEADER_LEN + 1; size_t payload_len = len + 1;
size_t gwbuf_len = MYSQL_HEADER_LEN + payload_len;
GWBUF* gwbuf = gwbuf_alloc(gwbuf_len); GWBUF* gwbuf = gwbuf_alloc(gwbuf_len);
*((unsigned char*)((char*)GWBUF_DATA(gwbuf))) = len; *((unsigned char*)((char*)GWBUF_DATA(gwbuf))) = payload_len;
*((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 1)) = (len >> 8); *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 1)) = (payload_len >> 8);
*((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 2)) = (len >> 16); *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 2)) = (payload_len >> 16);
*((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 3)) = 0x00; *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 3)) = 0x00;
*((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 4)) = 0x03; *((unsigned char*)((char*)GWBUF_DATA(gwbuf) + 4)) = 0x03;
memcpy((char*)GWBUF_DATA(gwbuf) + 5, s.c_str(), s.length() + 1); memcpy((char*)GWBUF_DATA(gwbuf) + 5, s.c_str(), len);
return gwbuf; return gwbuf;
} }