]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
map: prevent crash on unrepresentable responses
authorPetr Špaček <petr.spacek@nic.cz>
Tue, 20 Oct 2020 11:51:54 +0000 (13:51 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Mon, 26 Oct 2020 13:25:15 +0000 (14:25 +0100)
Typical example of unrepresentable message is a Lua error.
E.g. error() called from kresc would lead to NULL message.

NEWS
daemon/io.c

diff --git a/NEWS b/NEWS
index 871a4b40ba29f63851e03610cd97cad68c9ef611..17bbc385be17293a2b7cc0d231dcfe480d373daa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ Bugfixes
 - avoid an assert() error in stash_rrset() (!1072)
 - fix emergency cache locking bug introduced in 5.1.3 (!1078)
 - migrate map() command to control sockets; fix systemd integration (!1000)
+- fix crash when sending back errors over control socket (!1000)
 
 Incompatible changes
 --------------------
index 2552ba107e67f38a4d66bbe865f6c1f34b910b49..5d2c7727acc778c9251e928e3e9ac2d905840b53 100644 (file)
@@ -667,20 +667,24 @@ void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *bu
                }
 
                int ret = engine_cmd(L, cmd, false);
-               const char *message = "";
+               const char *message = NULL;
+               size_t len_s;
                if (lua_gettop(L) > 0) {
-                       message = lua_tostring(L, -1);
+                       message = lua_tolstring(L, -1, &len_s);
                }
 
                /* Simpler output in binary mode */
                if (data->mode == io_mode_binary) {
-                       size_t len_s = strlen(message);
-                       if (len_s > UINT32_MAX) {
-                               goto next_iter;
+                       /* Leader expects length field in all cases */
+                       if (!message || len_s > UINT32_MAX) {
+                               kr_log_error("[io] unrepresentable respose on control socket, "
+                                               "sending back empty block (command '%s')\n", cmd);
+                               len_s = 0;
                        }
                        uint32_t len_n = htonl(len_s);
                        fwrite(&len_n, sizeof(len_n), 1, out);
-                       fwrite(message, len_s, 1, out);
+                       if (len_s > 0)
+                               fwrite(message, len_s, 1, out);
                        goto next_iter;
                }