]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Fix defects detected by Coverity Scan
authorOto Šťáva <oto.stava@nic.cz>
Fri, 25 Feb 2022 06:46:13 +0000 (07:46 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 28 Feb 2022 13:26:38 +0000 (14:26 +0100)
Targeted CIDs: 155456, 155962, 346121, 346123, 346124, 346125,
  346126, 346127, 346130, 346131, 346132, 346134, 346135, 346138,
  346140, 346145, 346146, 346149, 346152, 346154, 346156, 346157

lib/dnssec/nsec3.c change:
  apparently cleaning fallout from my (= vcunat's) commit b5cf61325ae

16 files changed:
daemon/bindings/impl.h
daemon/http.c
daemon/io.c
daemon/main.c
daemon/udp_queue.c
daemon/worker.c
lib/dnssec/nsec3.c
lib/generic/queue.c
lib/generic/test_pack.c
lib/resolve.c
lib/test_module.c
lib/test_rplan.c
lib/utils.c
utils/cache_gc/db.c
utils/cache_gc/kr_cache_gc.c
utils/client/kresc.c

index 7e085cf3bdb141ccdb86c5387a72e5b927619ac4..5b923b5225b57d3d971a1ebaf5a7537664f52299 100644 (file)
@@ -83,7 +83,7 @@ static inline int execute_callback(lua_State *L, int argc)
  */
 static inline void lua_pushpointer(lua_State *L, void *p)
 {
-       void *addr = lua_newuserdata(L, sizeof(void *));
+       void **addr = lua_newuserdata(L, sizeof(void *));
        kr_require(addr);
        memcpy(addr, &p, sizeof(void *));
 }
index 0f9551d287e8491690828cd2484a6043ddc174de..f6f7bf6b683b848cb0a795cced5519726eb09540 100644 (file)
@@ -216,7 +216,6 @@ static int process_uri_path(struct http_ctx *ctx, const char* path, int32_t stre
        char *beg = strstr(path, key);
        char *end;
        size_t remaining;
-       ssize_t ret;
        uint8_t *dest;
 
        if (!beg)  /* No dns variable in path. */
@@ -231,10 +230,10 @@ static int process_uri_path(struct http_ctx *ctx, const char* path, int32_t stre
        remaining = ctx->buf_size - ctx->submitted - ctx->buf_pos;
        dest = ctx->buf + ctx->buf_pos;
 
-       ret = kr_base64url_decode((uint8_t*)beg, end - beg, dest, remaining);
+       int ret = kr_base64url_decode((uint8_t*)beg, end - beg, dest, remaining);
        if (ret < 0) {
                ctx->buf_pos = 0;
-               kr_log_debug(DOH, "[%p] base64url decode failed %s\n", (void *)ctx->h2, strerror(ret));
+               kr_log_debug(DOH, "[%p] base64url decode failed %s\n", (void *)ctx->h2, kr_strerror(ret));
                return ret;
        }
 
index d7ae84e95487187e907d61a5d0564a067120c7be..e8b6f17796f45b79b9777707628e007c6d3c54b1 100644 (file)
@@ -183,29 +183,42 @@ int io_bind(const struct sockaddr *addr, int type, const endpoint_flags_t *flags
 
        int yes = 1;
        if (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) {
-               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) {
+                       close(fd);
                        return kr_error(errno);
+               }
 
 #ifdef SO_REUSEPORT_LB
-               if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &yes, sizeof(yes)))
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &yes, sizeof(yes))) {
+                       close(fd);
                        return kr_error(errno);
+               }
 #elif defined(SO_REUSEPORT) && defined(__linux__) /* different meaning on (Free)BSD */
-               if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) {
+                       close(fd);
                        return kr_error(errno);
+               }
 #endif
 
 #ifdef IPV6_V6ONLY
                if (addr->sa_family == AF_INET6
-                   && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)))
+                   && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes))) {
+                       close(fd);
                        return kr_error(errno);
+               }
 #endif
                if (flags != NULL && flags->freebind) {
                        int optlevel;
                        int optname;
                        int ret = family_to_freebind_option(addr->sa_family, &optlevel, &optname);
-                       if (ret) return kr_error(ret);
-                       if (setsockopt(fd, optlevel, optname, &yes, sizeof(yes)))
+                       if (ret) {
+                               close(fd);
+                               return kr_error(ret);
+                       }
+                       if (setsockopt(fd, optlevel, optname, &yes, sizeof(yes))) {
+                               close(fd);
                                return kr_error(errno);
+                       }
                }
 
                /* Linux 3.15 has IP_PMTUDISC_OMIT which makes sockets
@@ -226,8 +239,10 @@ int io_bind(const struct sockaddr *addr, int type, const endpoint_flags_t *flags
 #endif
        }
 
-       if (bind(fd, addr, kr_sockaddr_len(addr)))
+       if (bind(fd, addr, kr_sockaddr_len(addr))) {
+               close(fd);
                return kr_error(errno);
+       }
 
        return fd;
 }
@@ -721,11 +736,11 @@ void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *bu
        char *cmd, *cmd_next = NULL;
        bool incomplete_cmd = false;
 
-       if (!(stream && commands && nread > 0)) {
+       if (!commands || nread <= 0) {
                goto finish;
        }
-       /* Execute */
 
+       /* Execute */
        if (commands[nread - 1] != '\n') {
                incomplete_cmd = true;
        }
@@ -859,24 +874,30 @@ struct io_stream_data *io_tty_alloc_data() {
 
 void io_tty_accept(uv_stream_t *master, int status)
 {
-       struct io_stream_data *data = io_tty_alloc_data();
        /* We can't use any allocations after mp_start() and it's easier anyway. */
        uv_pipe_t *client = malloc(sizeof(*client));
+       if (!client)
+               return;
+
+       struct io_stream_data *data = io_tty_alloc_data();
+       if (!data) {
+               free(client);
+               return;
+       }
        client->data = data;
 
        struct args *args = the_args;
-       if (client && client->data) {
-                uv_pipe_init(master->loop, client, 0);
-                if (uv_accept(master, (uv_stream_t *)client) != 0) {
-                       mp_delete(data->pool->ctx);
-                       return;
-                }
-                uv_read_start((uv_stream_t *)client, io_tty_alloc, io_tty_process_input);
-                /* Write command line */
-                if (!args->quiet) {
-                       uv_buf_t buf = { "> ", 2 };
-                       uv_try_write((uv_stream_t *)client, &buf, 1);
-                }
+       uv_pipe_init(master->loop, client, 0);
+       if (uv_accept(master, (uv_stream_t *)client) != 0) {
+               mp_delete(data->pool->ctx);
+               return;
+       }
+       uv_read_start((uv_stream_t *)client, io_tty_alloc, io_tty_process_input);
+
+       /* Write command line */
+       if (!args->quiet) {
+               uv_buf_t buf = { "> ", 2 };
+               uv_try_write((uv_stream_t *)client, &buf, 1);
        }
 }
 
index 42932ec56733eff85ec5c545d4441e2b334fcd52..d03d3c1e5266bcd8dc78b2526549b3d59d2373ca 100644 (file)
@@ -159,6 +159,8 @@ static int run_worker(uv_loop_t *loop, struct engine *engine, bool leader, struc
 
        /* Control sockets or TTY */
        uv_pipe_t *pipe = malloc(sizeof(*pipe));
+       if (!pipe)
+               return EXIT_FAILURE;
        uv_pipe_init(loop, pipe, 0);
        if (args->interactive) {
                if (!args->quiet)
index b466f2f3263be925a5c7ecfcbf1fa3ce7edc46ce..a2050f110359dfda968e01190ff228e4ebea12e5 100644 (file)
@@ -44,6 +44,8 @@ typedef struct {
 static udp_queue_t * udp_queue_create()
 {
        udp_queue_t *q = calloc(1, sizeof(*q));
+       kr_require(q != NULL);
+
        for (int i = 0; i < UDP_QUEUE_LEN; ++i) {
                struct msghdr *mhi = &q->msgvec[i].msg_hdr;
                /* These shall remain always the same. */
index 00782081eeb34d09d72bc82c2a0abeaacd171c08..63e866103baa3003404140405cebb744e508825b 100644 (file)
@@ -828,13 +828,6 @@ static int qr_task_send(struct qr_task *task, struct session *session,
                worker_task_pkt_set_msgid(task, msg_id);
        }
 
-       uv_handle_t *ioreq = malloc(is_stream ? sizeof(uv_write_t) : sizeof(uv_udp_send_t));
-       if (!ioreq)
-               return qr_task_on_send(task, handle, kr_error(ENOMEM));
-
-       /* Pending ioreq on current task */
-       qr_task_ref(task);
-
        struct worker_ctx *worker = ctx->worker;
        /* Note time for upstream RTT */
        task->send_time = kr_now();
@@ -842,6 +835,14 @@ static int qr_task_send(struct qr_task *task, struct session *session,
        /* Send using given protocol */
        if (kr_fails_assert(!session_flags(session)->closing))
                return qr_task_on_send(task, NULL, kr_error(EIO));
+
+       uv_handle_t *ioreq = malloc(is_stream ? sizeof(uv_write_t) : sizeof(uv_udp_send_t));
+       if (!ioreq)
+               return qr_task_on_send(task, handle, kr_error(ENOMEM));
+
+       /* Pending ioreq on current task */
+       qr_task_ref(task);
+
        if (session_flags(session)->has_http) {
 #if ENABLE_DOH2
                uv_write_t *write_req = (uv_write_t *)ioreq;
index 8d9245014c2bad4b21606453e9fc2f4977b9ed32..e260b0460247e8ac538bb3d1b459b7a6fd718801 100644 (file)
@@ -650,7 +650,6 @@ int kr_nsec3_ref_to_unsigned(const knot_pkt_t *pkt)
                if (ns->type != KNOT_RRTYPE_NS)
                        continue;
 
-               int flags = 0;
                bool nsec3_found = false;
                for (unsigned j = 0; j < sec->count; ++j) {
                        const knot_rrset_t *nsec3 = knot_pkt_rr(sec, j);
@@ -680,13 +679,6 @@ int kr_nsec3_ref_to_unsigned(const knot_pkt_t *pkt)
                }
                if (!nsec3_found)
                        return kr_error(DNSSEC_NOT_FOUND);
-               if (flags & FLG_NAME_MATCHED) {
-                       /* nsec3 which owner matches
-                        * the delegation name was found,
-                        * but nsec3 type bitmap contains wrong types
-                        */
-                       return kr_error(EINVAL);
-               }
                /* nsec3 that matches the delegation was not found.
                 * Check rfc5155, 8.9. paragraph 4.
                 * Find closest provable encloser.
index 1e49f22b5f4281ee3734cea983e0e83fde852288..7a458cd382b4e8adcb0782f6ac28990555b5f832 100644 (file)
@@ -36,8 +36,9 @@ void queue_deinit_impl(struct queue *q)
 
 static struct queue_chunk * queue_chunk_new(const struct queue *q)
 {
+       /* size_t cast is to avoid unintended sign-extension */
        struct queue_chunk *c = malloc(offsetof(struct queue_chunk, data)
-                                       + q->chunk_cap * q->item_size);
+                                       + (size_t) q->chunk_cap * (size_t) q->item_size);
        if (unlikely(!c)) abort(); // simplify stuff
        memset(c, 0, offsetof(struct queue_chunk, data));
        c->cap = q->chunk_cap;
@@ -57,9 +58,10 @@ void * queue_push_impl(struct queue *q)
        } else
        if (t->end == t->cap) {
                if (t->begin * 2 >= t->cap) {
-                       /* Utilization is below 50%, so let's shift (no overlap). */
+                       /* Utilization is below 50%, so let's shift (no overlap).
+                        * (size_t cast is to avoid unintended sign-extension) */
                        memcpy(t->data, t->data + t->begin * q->item_size,
-                               (t->end - t->begin) * q->item_size);
+                               (size_t) (t->end - t->begin) * (size_t) q->item_size);
                        t->end -= t->begin;
                        t->begin = 0;
                } else {
@@ -91,10 +93,11 @@ void * queue_push_head_impl(struct queue *q)
        if (h->begin == 0) {
                if (h->end * 2 <= h->cap) {
                        /* Utilization is below 50%, so let's shift (no overlap).
-                        * Computations here are simplified due to h->begin == 0. */
+                        * Computations here are simplified due to h->begin == 0.
+                        * (size_t cast is to avoid unintended sign-extension) */
                        const int cnt = h->end;
                        memcpy(h->data + (h->cap - cnt) * q->item_size, h->data,
-                               cnt * q->item_size);
+                               (size_t) cnt * (size_t) q->item_size);
                        h->begin = h->cap - cnt;
                        h->end = h->cap;
                } else {
index f25c1997f6e473c4b1ad6ae7562a23928f6eecca..692f253dd164f3eb6d469723f39b7064b55d3a68 100644 (file)
@@ -36,12 +36,10 @@ static void test_pack_std(void **state)
        /* Iterate */
        uint8_t *it = pack_head(pack);
        assert_non_null(it);
-       unsigned count = 0;
        while (it != pack_tail(pack)) {
                assert_int_equal(pack_obj_len(it), 2);
                assert_true(memcmp(pack_obj_val(it), "de", 2) == 0);
                it = pack_obj_next(it);
-               count += 1;
        }
 
        /* Find */
index 4559bc0de8447a6157ccc6aa4241c3438b064314..45030fb0cefd02fbb0822ad41c1717f35b319fb7 100644 (file)
@@ -548,27 +548,26 @@ static void answer_finalize(struct kr_request *request)
        /* AD flag.  We can only change `secure` from true to false.
         * Be conservative.  Primary approach: check ranks of all RRs in wire.
         * Only "negative answers" need special handling. */
-       bool secure = last != NULL && request->state == KR_STATE_DONE /*< suspicious otherwise */
+       bool secure = request->state == KR_STATE_DONE /*< suspicious otherwise */
                && knot_pkt_qtype(answer) != KNOT_RRTYPE_RRSIG;
-       if (last && (last->flags.STUB)) {
+       if (last->flags.STUB) {
                secure = false; /* don't trust forwarding for now */
        }
-       if (last && (last->flags.DNSSEC_OPTOUT)) {
+       if (last->flags.DNSSEC_OPTOUT) {
                VERBOSE_MSG(last, "insecure because of opt-out\n");
                secure = false; /* the last answer is insecure due to opt-out */
        }
 
        /* Write all RRsets meant for the answer. */
-       const uint16_t reorder = last ? last->reorder : 0;
        bool answ_all_cnames = false/*arbitrary*/;
        if (knot_pkt_begin(answer, KNOT_ANSWER)
-           || write_extra_ranked_records(&request->answ_selected, reorder,
+           || write_extra_ranked_records(&request->answ_selected, last->reorder,
                                        answer, &secure, &answ_all_cnames)
            || knot_pkt_begin(answer, KNOT_AUTHORITY)
-           || write_extra_ranked_records(&request->auth_selected, reorder,
+           || write_extra_ranked_records(&request->auth_selected, last->reorder,
                                        answer, &secure, NULL)
            || knot_pkt_begin(answer, KNOT_ADDITIONAL)
-           || write_extra_ranked_records(&request->add_selected, reorder,
+           || write_extra_ranked_records(&request->add_selected, last->reorder,
                                        answer, NULL/*not relevant to AD*/, NULL)
            || answer_append_edns(request)
           )
@@ -577,7 +576,6 @@ static void answer_finalize(struct kr_request *request)
                return;
        }
 
-       if (!last) secure = false; /*< should be no-op, mostly documentation */
        /* AD: "negative answers" need more handling. */
        if (kr_response_classify(answer) != PKT_NOERROR
            /* Additionally check for CNAME chains that "end in NODATA",
@@ -812,32 +810,31 @@ int kr_resolve_consume(struct kr_request *request, struct kr_transport **transpo
                return KR_STATE_FAIL;
        }
        bool tried_tcp = (qry->flags.TCP);
-       if (!packet || packet->size == 0) {
+       if (!packet || packet->size == 0)
                return KR_STATE_PRODUCE;
+
+       /* Packet cleared, derandomize QNAME. */
+       knot_dname_t *qname_raw = knot_pkt_qname(packet);
+       if (qname_raw && qry->secret != 0) {
+               randomized_qname_case(qname_raw, qry->secret);
+       }
+       request->state = KR_STATE_CONSUME;
+       if (qry->flags.CACHED) {
+               ITERATE_LAYERS(request, qry, consume, packet);
        } else {
-               /* Packet cleared, derandomize QNAME. */
-               knot_dname_t *qname_raw = knot_pkt_qname(packet);
-               if (qname_raw && qry->secret != 0) {
-                       randomized_qname_case(qname_raw, qry->secret);
-               }
-               request->state = KR_STATE_CONSUME;
-               if (qry->flags.CACHED) {
-                       ITERATE_LAYERS(request, qry, consume, packet);
-               } else {
-                       /* Fill in source and latency information. */
-                       request->upstream.rtt = kr_now() - qry->timestamp_mono;
-                       request->upstream.transport = transport ? *transport : NULL;
-                       ITERATE_LAYERS(request, qry, consume, packet);
-                       /* Clear temporary information */
-                       request->upstream.transport = NULL;
-                       request->upstream.rtt = 0;
-               }
+               /* Fill in source and latency information. */
+               request->upstream.rtt = kr_now() - qry->timestamp_mono;
+               request->upstream.transport = transport ? *transport : NULL;
+               ITERATE_LAYERS(request, qry, consume, packet);
+               /* Clear temporary information */
+               request->upstream.transport = NULL;
+               request->upstream.rtt = 0;
        }
 
        if (transport && !qry->flags.CACHED) {
                if (!(request->state & KR_STATE_FAIL)) {
                        /* Do not complete NS address resolution on soft-fail. */
-                       const int rcode = packet ? knot_wire_get_rcode(packet->wire) : 0;
+                       const int rcode = knot_wire_get_rcode(packet->wire);
                        if (rcode != KNOT_RCODE_SERVFAIL && rcode != KNOT_RCODE_REFUSED) {
                                qry->flags.AWAIT_IPV6 = false;
                                qry->flags.AWAIT_IPV4 = false;
index 592f5355e8873f1636499ec4f675dd6fa8d4f418..5a8acfc0f7afbf52e698a8d53daaa9447ad60bb2 100644 (file)
@@ -7,7 +7,7 @@
 
 static void test_module_params(void **state)
 {
-       struct kr_module module;
+       struct kr_module module = { 0 };
        assert_int_equal(kr_module_load(NULL, NULL, NULL), kr_error(EINVAL));
        assert_int_equal(kr_module_load(&module, NULL, NULL), kr_error(EINVAL));
        kr_module_unload(NULL);
@@ -15,14 +15,14 @@ static void test_module_params(void **state)
 
 static void test_module_builtin(void **state)
 {
-       struct kr_module module;
+       struct kr_module module = { 0 };
        assert_int_equal(kr_module_load(&module, "iterate", NULL), 0);
        kr_module_unload(&module);
 }
 
 static void test_module_c(void **state)
 {
-       struct kr_module module;
+       struct kr_module module = { 0 };
        assert_int_equal(kr_module_load(&module, "mock_cmodule", "tests/unit"), 0);
        kr_module_unload(&module);
 }
index e041973708f49f70316153c85aa88390942a3cc6..e56ea87dbe2f850b1da4e93822d52990f247ad0e 100644 (file)
@@ -28,7 +28,7 @@ static void test_rplan_params(void **state)
 
 static void test_rplan_push(void **state)
 {
-       knot_mm_t mm;
+       knot_mm_t mm = { 0 };
        test_mm_ctx_init(&mm);
        struct kr_request request = {
                .pool = mm,
index 9ba845d2ffd44963b9e49e74f86373b5f28272d3..57b9512f1ad1a4adab4d4acfaf9d849d92da6652 100644 (file)
@@ -109,7 +109,7 @@ char* kr_strcatdup(unsigned n, ...)
        /* Allocate result and fill */
        char *result = NULL;
        if (total_len > 0) {
-               if (unlikely(total_len + 1 == 0)) return NULL;
+               if (unlikely(total_len == SIZE_MAX)) return NULL;
                result = malloc(total_len + 1);
        }
        if (result) {
@@ -335,9 +335,14 @@ void kr_inaddr_set_port(struct sockaddr *addr, uint16_t port)
                return;
        }
        switch (addr->sa_family) {
-       case AF_INET:  ((struct sockaddr_in *)addr)->sin_port = htons(port);
-       case AF_INET6: ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
-       default: break;
+       case AF_INET:
+               ((struct sockaddr_in *)addr)->sin_port = htons(port);
+               break;
+       case AF_INET6:
+               ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
+               break;
+       default:
+               break;
        }
 }
 
@@ -729,7 +734,10 @@ int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr,
                return kr_error(ENOMEM);
        }
        rr_new->rrs = rr->rrs;
-       if (kr_fails_assert(rr_new->additional == NULL)) return kr_error(EINVAL);
+       if (kr_fails_assert(rr_new->additional == NULL)) {
+               mm_free(pool, entry);
+               return kr_error(EINVAL);
+       }
 
        entry->qry_uid = qry_uid;
        entry->rr = rr_new;
index 923da87a58f0f7599ed278ad05be265cc5c30c36..fc4a2fdbacd226b68527add07c6d9dacff8f49ca 100644 (file)
@@ -200,7 +200,7 @@ int kr_gc_cache_iter(knot_db_t * knot_db, const  kr_cache_gc_cfg_t *cfg,
 
                info.entry_size = key.len + val.len;
                info.valid = false;
-               const int entry_type = ret == KNOT_EOK ? kr_gc_key_consistent(key) : -1;
+               const int entry_type = kr_gc_key_consistent(key);
                const struct entry_h *entry = NULL;
                if (entry_type >= 0) {
                        counter_gc_consistent++;
index dc56058b390b8c64adfbbfafd9702ee60a716300..5978345c79498c84ff6599a56b4665d4609335d9 100644 (file)
@@ -115,6 +115,7 @@ int cb_delete_categories(const knot_db_val_t * key, gc_record_info_t * info,
                if ((ctx->cfg_temp_keys_space > 0 &&
                     used > ctx->cfg_temp_keys_space) || todelete == NULL) {
                        ctx->oversize_records++;
+                       free(todelete);
                } else {
                        entry_dynarray_add(&ctx->to_delete, &todelete);
                        ctx->used_space = used;
index 1c8615e760a7493d489e925490c4d3e0d915d0fb..2dc107c3ac1f7fd9f8f1421c7189747a49220df6 100644 (file)
@@ -37,7 +37,7 @@ bool starts_with(const char *a, const char *b)
 }
 
 //! Returns Lua name of type of value, NULL on error. Puts length of type in name_len;
-const char *get_type_name(const char *value)
+char *get_type_name(const char *value)
 {
        if (value == NULL) {
                return NULL;
@@ -51,7 +51,6 @@ const char *get_type_name(const char *value)
        }
 
        char *cmd = afmt("type(%s)", value);
-
        if (!cmd) {
                perror("While tab-completing.");
                return NULL;
@@ -61,16 +60,15 @@ const char *get_type_name(const char *value)
        char *type = run_cmd(cmd, &name_len);
        if (!type) {
                return NULL;
-       } else {
-               free(cmd);
        }
+       free(cmd);
 
        if (starts_with(type, "[")) {
                //Return "nil" on non-valid name.
                free(type);
-               return "nil";
+               return strdup("nil");
        } else {
-               type[(strlen(type)) - 1] = '\0';
+               type[strlen(type) - 1] = '\0';
                return type;
        }
 }
@@ -145,7 +143,7 @@ static void complete_members(EditLine * el, const char *str,
                } else {
                        //Print members matching the current line.
                        while (token) {
-                               if (str && starts_with(token, dot + 1)) {
+                               if (starts_with(token, dot + 1)) {
                                        const char *member_type =
                                            get_type_name(afmt
                                                          ("%s.%s", table,
@@ -204,7 +202,9 @@ static void complete_globals(EditLine * el, const char *str, int str_len)
        char *lastmatch = NULL;
        while (token) {
                if (str && starts_with(token, str)) {
-                       printf("\n%s (%s)", token, get_type_name(token));
+                       char *name = get_type_name(token);
+                       printf("\n%s (%s)", token, name);
+                       free(name);
                        lastmatch = token;
                        matches++;
                }
@@ -332,6 +332,8 @@ static char *run_cmd(const char *cmd, size_t * out_len)
        if (!fread(&len, sizeof(len), 1, g_tty))
                return NULL;
        len = ntohl(len);
+       if (!len)
+               return NULL;
        char *msg = malloc(1 + (size_t) len);
        if (!msg)
                return NULL;