Bug #49248 Proxy crashes when attempting to access resultset.fields on an error packet
Submitted: 1 Dec 2009 3:34 Modified: 9 Jan 2015 16:01
Reporter: Lachlan Mulcahy Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Proxy: Core Severity:S2 (Serious)
Version:0.7.2 OS:Any
Assigned to: Assigned Account CPU Architecture:Any

[1 Dec 2009 3:34] Lachlan Mulcahy
Description:
If running a LUA script and processing a packet in read_query_result(), attempting to access the fields array within the resultset returned will cause the proxy to crash.

2009-12-01 13:25:19: (critical) network-mysqld-proto.c:115: bytestream[4] is 255
**
** ERROR:(network-mysqld-packet.c:668):network_mysqld_proto_get_fielddefs: assertion failed: (chunk)

How to repeat:
Create a LUA script with:

function read_query_result(inj)
  fields = inj.resultset.fields
  return
end

Run the proxy with this script and attempt to issue an intentionally incorrect syntax query connection via it. eg.

mysql> abc;

Observe the proxy fail an assertion in the network_mysqld_proto_get_fielddefs function.

Note: A workaround for this is to check (inj.resultset.query_stats == proxy.MYSQLD_QUERY_OK) before proceeding.

Suggested fix:
Proxy should handle a reference to resultset.fields for errors more gracefully. Returning an empty array rather than crashing seems best.
[1 Dec 2009 6:35] Alexey Kishkin
verified, but it requires little bit more than just read_query_result:

- must be function read_query() as well, which must return proxy.PROXY_SEND_QUERY and use {resultset_is_neede=true} in the proxy.query:append().

I use following procedure for verification
lua file ax.lua:
walrus@walrus-note:~$ cat mp/ax.lua 
function read_query( packet )

  if string.byte(packet) == proxy.COM_QUERY then
     local query = string.sub(packet, 2)
     print("we got a normal query: " .. query)
    local f_s, f_e, command = string.find(packet, "^%s*(%w+)", 2)
    local option
    if f_e then
      f_s, f_e, option = string.find(packet, "^%s+(%w+)", f_e + 1)
   end
   if command == "bug" then
     proxy.queries:append(1, string.char(proxy.COM_QUERY) .. "BUG" , {resultset_is_needed = true}) 
     return proxy.PROXY_SEND_QUERY
   elseif command == "who" then
     proxy.queries:append(1, string.char(proxy.COM_QUERY) .. "SHOW PROCESSLIST" )
     return proxy.PROXY_SEND_QUERY
   end
 end
end
 

function read_query_result ( inj )
  print("Script invocation ".. inj.type)
  fields = inj.resultset.fields
  return
end

run mysql proxy as:
sbin/mysql-proxy --proxy-backend-addresses=127.0.0.1:3306 --proxy-lua-script=ax.lua --log-level=debug --log-file=logfile1.log

then in another xterm:
walrus@walrus-note:~$ mysql  -h 127.0.0.1 -P 4040

mysql> abc;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'abc' at line 1
mysql> bug;
ERROR 2013 (HY000): Lost connection to MySQL server during query

in the mysql-proxy window appears:

we got a normal query: abc
we got a normal query: bug
Script invocation 1
**
** ERROR:(network-mysqld-packet.c:668):???: assertion failed: (chunk)
Abort (core dumped)