<HTML><BODY><div><div>Hi!<br><br>Thanks to @igormunkin we discovered more details of this problem.<br>Turns out we can see lua_State stored in port and it seems that<br>something is totally wrong here: it points to some function address<br>(port_lua_dump_16()). Thus I will make some more research into it and<br>this patch should be discarded for now.<br>(gdb) p ((struct port_lua *)port)->vtab<br>$19 = (const port_vtab *) 0x4e759f <port_lua_dump><br>(gdb) p ((struct port_lua *)port)->L<br>$20 = (lua_State *) 0x4e75c9 <port_lua_dump_16></div><div> </div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">Среда, 22 июля 2020, 11:59 +03:00 от Nikita Pettik <korablev@tarantool.org>:<br> <div id=""><div class="js-helper js-readmsg-msg"><style type="text/css"></style><div><div id="style_15954083971483481276_BODY">On 22 Jul 01:32, Ilya Kosarev wrote:<br>> (gdb) p port->vtab->dump_msgpack<br>> count = port_dump_msgpack_16(&port, out);<br>> else<br>> count = port_dump_msgpack(&port, out);<br>> port_destroy(&port);<br>> if (count < 0) {<br>> obuf_rollback_to_svp(out, &svp);<br>> goto error;<br>> }<br>><br>> iproto_reply_select(out, &svp, msg->header.sync,<br>> ::schema_version, count);<br>> iproto_wpos_create(&msg->wpos, out);<br>> return;<br>> error:<br>> tx_reply_error(msg);<br>> }<br>><br>> As we can see, we fail to the error path through count == -1. It comes<br>> from port_lua_dump() calling port_lua_do_dump() with encode_lua_call().<br>><br>> static int<br>> port_lua_dump(struct port *base, struct obuf *out)<br>> {<br>> return port_lua_do_dump(base, out, encode_lua_call);<br>> }<br>><br>> encode_lua_call() actually sets port->size equal to lua_gettop(), being<br>> returned by port_lua_do_dump().<br><br>As a first assumption it is OK. But there might be other reasons<br>for negative value in size var. For instance, out-of-bound memory<br>access in luamp_encode() which overwrites value of stack var..<br> <br>> src/lj_api.c | 7 ++++++-<br>> 1 file changed, 6 insertions(+), 1 deletion(-)<br>><br>> diff --git a/src/lj_api.c b/src/lj_api.c<br>> index c9b5d22..5ca2c57 100644<br>> --- a/src/lj_api.c<br>> +++ b/src/lj_api.c<br>> @@ -135,7 +135,12 @@ LUA_API const lua_Number *lua_version(lua_State *L)<br>><br>> LUA_API int lua_gettop(lua_State *L)<br>> {<br>> - return (int)(L->top - L->base);<br>> + int stack_size = (int)(L->top - L->base);<br>> + /*<br>> + * Stack size has to be non-negative according to Lua reference manual.<br>> + */<br>> + assert(stack_size >= 0);<br>> + return stack_size;<br>> }<br>><br>> LUA_API void lua_settop(lua_State *L, int idx)<br>> --<br>> 2.17.1<br>></div></div></div></div></blockquote> <div> </div><div data-signature-widget="container"><div data-signature-widget="content"><div>--<br>Ilya Kosarev</div></div></div><div> </div></div></BODY></HTML>