Fix more memory leaks found by ASAN.
authorKirill Isakov <is-kir@ya.ru>
Sun, 25 Jul 2021 11:15:24 +0000 (17:15 +0600)
committerKirill Isakov <is-kir@ya.ru>
Sun, 25 Jul 2021 15:04:43 +0000 (21:04 +0600)
src/address_cache.c
src/fsck.c
src/invitation.c
src/net_setup.c
src/net_socket.c
src/protocol_auth.c
src/tincctl.c
test/splice.c

index b6d48d0..df465da 100644 (file)
@@ -67,6 +67,7 @@ static struct addrinfo *get_known_addresses(node_t *n) {
 static void free_known_addresses(struct addrinfo *ai) {
        for(struct addrinfo *aip = ai, *next; aip; aip = next) {
                next = aip->ai_next;
+               free(aip->ai_addr);
                free(aip);
        }
 }
index a60dcf3..f10fe3c 100644 (file)
@@ -234,6 +234,7 @@ int fsck(const char *argv0) {
                        // Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file.
                        fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
                        fprintf(stderr, "Please correct this error.\n");
+                       free(name);
                        return 1;
                }
        } else {
@@ -241,6 +242,7 @@ int fsck(const char *argv0) {
 
                if(!f) {
                        fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
+                       free(name);
                        return 1;
                }
 
@@ -251,6 +253,7 @@ int fsck(const char *argv0) {
                        fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
                        fprintf(stderr, "You can generate a new RSA key with:\n\n");
                        print_tinc_cmd(argv0, "generate-rsa-keys");
+                       free(name);
                        return 1;
                }
 
@@ -283,6 +286,7 @@ int fsck(const char *argv0) {
                        // Something is seriously wrong here. If we can access the directory with tinc.conf in it, we should certainly be able to stat() an existing file.
                        fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
                        fprintf(stderr, "Please correct this error.\n");
+                       free(name);
                        return 1;
                }
        } else {
@@ -290,6 +294,7 @@ int fsck(const char *argv0) {
 
                if(!f) {
                        fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
+                       free(name);
                        return 1;
                }
 
@@ -300,6 +305,7 @@ int fsck(const char *argv0) {
                        fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
                        fprintf(stderr, "You can generate a new Ed25519 key with:\n\n");
                        print_tinc_cmd(argv0, "generate-ed25519-keys");
+                       free(name);
                        return 1;
                }
 
@@ -333,6 +339,7 @@ int fsck(const char *argv0) {
 #endif
                fprintf(stderr, "You can generate new keys with:\n\n");
                print_tinc_cmd(argv0, "generate-keys");
+               free(name);
                return 1;
        }
 
@@ -341,6 +348,8 @@ int fsck(const char *argv0) {
 
        snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, name);
 
+       free(name);
+
        if(access(fname, R_OK)) {
                fprintf(stderr, "WARNING: cannot read %s\n", fname);
        }
@@ -382,6 +391,9 @@ int fsck(const char *argv0) {
 
                        if(len != rsa_size(rsa_pub)) {
                                fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
+                               rsa_free(rsa_pub);
+                               rsa_free(rsa_priv);
+                               free(ecdsa_priv);
                                return 1;
                        }
 
@@ -409,18 +421,28 @@ int fsck(const char *argv0) {
                                fprintf(stderr, "ERROR: public RSA key does not work.\n");
                        }
 
+
+                       rsa_free(rsa_pub);
+                       rsa_pub = NULL;
+
                        free(buf3);
                        free(buf2);
                        free(buf1);
 
                        if(!result) {
+                               rsa_free(rsa_priv);
+                               free(ecdsa_priv);
                                return 1;
                        }
-
                }
+
+               rsa_free(rsa_priv);
+               rsa_priv = NULL;
        } else {
                if(rsa_pub) {
                        fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n");
+                       rsa_free(rsa_pub);
+                       rsa_pub = NULL;
                }
        }
 
@@ -464,16 +486,21 @@ int fsck(const char *argv0) {
                        // TODO: suggest remedies
                        char *key1 = ecdsa_get_base64_public_key(ecdsa_pub);
 
+                       free(ecdsa_pub);
+                       ecdsa_pub = NULL;
+
                        if(!key1) {
                                fprintf(stderr, "ERROR: public Ed25519 key does not work.\n");
+                               free(ecdsa_priv);
                                return 1;
                        }
 
                        char *key2 = ecdsa_get_base64_public_key(ecdsa_priv);
 
                        if(!key2) {
-                               free(key1);
                                fprintf(stderr, "ERROR: private Ed25519 key does not work.\n");
+                               free(ecdsa_priv);
+                               free(key1);
                                return 1;
                        }
 
@@ -483,12 +510,18 @@ int fsck(const char *argv0) {
 
                        if(result) {
                                fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n");
+                               free(ecdsa_priv);
                                return 1;
                        }
                }
+
+               free(ecdsa_priv);
+               ecdsa_priv = NULL;
        } else {
                if(ecdsa_pub) {
                        fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n");
+                       free(ecdsa_pub);
+                       ecdsa_pub = NULL;
                }
        }
 
index d615976..b2e35f9 100644 (file)
@@ -292,6 +292,7 @@ int cmd_invite(int argc, char *argv[]) {
                return 1;
        }
 
+       free(myname);
        myname = get_my_name(true);
 
        if(!myname) {
index a04f953..d4bc59e 100644 (file)
@@ -52,10 +52,11 @@ static io_t device_io;
 devops_t devops;
 bool device_standby = false;
 
-char *proxyhost;
-char *proxyport;
-char *proxyuser;
-char *proxypass;
+char *proxyhost = NULL;
+char *proxyport = NULL;
+char *proxyuser = NULL;
+char *proxypass = NULL;
+
 proxytype_t proxytype;
 bool autoconnect;
 bool disablebuggypeers;
@@ -435,18 +436,10 @@ char *get_name(void) {
 }
 
 bool setup_myself_reloadable(void) {
-       char *proxy = NULL;
-       char *rmode = NULL;
-       char *fmode = NULL;
-       char *bmode = NULL;
-       char *afname = NULL;
-       char *space;
-       bool choice;
-
        free(scriptinterpreter);
        scriptinterpreter = NULL;
-       get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &scriptinterpreter);
 
+       get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &scriptinterpreter);
 
        free(scriptextension);
 
@@ -454,9 +447,13 @@ bool setup_myself_reloadable(void) {
                scriptextension = xstrdup("");
        }
 
+       char *proxy = NULL;
+
        get_config_string(lookup_config(config_tree, "Proxy"), &proxy);
 
        if(proxy) {
+               char *space;
+
                if((space = strchr(proxy, ' '))) {
                        *space++ = 0;
                }
@@ -475,9 +472,22 @@ bool setup_myself_reloadable(void) {
                        proxytype = PROXY_EXEC;
                } else {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type %s!", proxy);
+                       free(proxy);
                        return false;
                }
 
+               free(proxyhost);
+               proxyhost = NULL;
+
+               free(proxyport);
+               proxyport = NULL;
+
+               free(proxyuser);
+               proxyuser = NULL;
+
+               free(proxypass);
+               proxypass = NULL;
+
                switch(proxytype) {
                case PROXY_NONE:
                default:
@@ -486,10 +496,11 @@ bool setup_myself_reloadable(void) {
                case PROXY_EXEC:
                        if(!space || !*space) {
                                logger(DEBUG_ALWAYS, LOG_ERR, "Argument expected for proxy type exec!");
+                               free(proxy);
                                return false;
                        }
 
-                       proxyhost =  xstrdup(space);
+                       proxyhost = xstrdup(space);
                        break;
 
                case PROXY_SOCKS4:
@@ -502,6 +513,14 @@ bool setup_myself_reloadable(void) {
                                *space++ = 0, proxyport = space;
                        }
 
+                       if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) {
+                               logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!");
+                               proxyport = NULL;
+                               proxyhost = NULL;
+                               free(proxy);
+                               return false;
+                       }
+
                        if(space && (space = strchr(space, ' '))) {
                                *space++ = 0, proxyuser = space;
                        }
@@ -510,11 +529,6 @@ bool setup_myself_reloadable(void) {
                                *space++ = 0, proxypass = space;
                        }
 
-                       if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) {
-                               logger(DEBUG_ALWAYS, LOG_ERR, "Host and port argument expected for proxy!");
-                               return false;
-                       }
-
                        proxyhost = xstrdup(proxyhost);
                        proxyport = xstrdup(proxyport);
 
@@ -532,6 +546,8 @@ bool setup_myself_reloadable(void) {
                free(proxy);
        }
 
+       bool choice;
+
        if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) {
                myself->options |= OPTION_INDIRECT;
        }
@@ -555,6 +571,8 @@ bool setup_myself_reloadable(void) {
        get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
        get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery);
 
+       char *rmode = NULL;
+
        if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) {
                if(!strcasecmp(rmode, "router")) {
                        routing_mode = RMODE_ROUTER;
@@ -564,12 +582,15 @@ bool setup_myself_reloadable(void) {
                        routing_mode = RMODE_HUB;
                } else {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Invalid routing mode!");
+                       free(rmode);
                        return false;
                }
 
                free(rmode);
        }
 
+       char *fmode = NULL;
+
        if(get_config_string(lookup_config(config_tree, "Forwarding"), &fmode)) {
                if(!strcasecmp(fmode, "off")) {
                        forwarding_mode = FMODE_OFF;
@@ -579,6 +600,7 @@ bool setup_myself_reloadable(void) {
                        forwarding_mode = FMODE_KERNEL;
                } else {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Invalid forwarding mode!");
+                       free(fmode);
                        return false;
                }
 
@@ -602,6 +624,8 @@ bool setup_myself_reloadable(void) {
        get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance);
        get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl);
 
+       char *bmode = NULL;
+
        if(get_config_string(lookup_config(config_tree, "Broadcast"), &bmode)) {
                if(!strcasecmp(bmode, "no")) {
                        broadcast_mode = BMODE_NONE;
@@ -611,6 +635,7 @@ bool setup_myself_reloadable(void) {
                        broadcast_mode = BMODE_DIRECT;
                } else {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Invalid broadcast mode!");
+                       free(bmode);
                        return false;
                }
 
@@ -626,7 +651,11 @@ bool setup_myself_reloadable(void) {
                        abort();
                }
 
-               subnet_add(NULL, s);
+               if(splay_search(subnet_tree, s)) {
+                       free(s);
+               } else {
+                       subnet_add(NULL, s);
+               }
        }
 
        for(config_t *cfg = lookup_config(config_tree, "BroadcastSubnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
@@ -636,7 +665,11 @@ bool setup_myself_reloadable(void) {
                        continue;
                }
 
-               subnet_add(NULL, s);
+               if(splay_search(subnet_tree, s)) {
+                       free(s);
+               } else {
+                       subnet_add(NULL, s);
+               }
        }
 
 #if !defined(IP_TOS)
@@ -668,6 +701,8 @@ bool setup_myself_reloadable(void) {
                maxtimeout = 900;
        }
 
+       char *afname = NULL;
+
        if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) {
                if(!strcasecmp(afname, "IPv4")) {
                        addressfamily = AF_INET;
@@ -677,6 +712,7 @@ bool setup_myself_reloadable(void) {
                        addressfamily = AF_UNSPEC;
                } else {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Invalid address family!");
+                       free(afname);
                        return false;
                }
 
@@ -762,6 +798,7 @@ static bool add_listen_address(char *address, bool bindto) {
 
                if(listen_sockets >= MAXSOCKETS) {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets");
+                       freeaddrinfo(ai);
                        return false;
                }
 
index 05ee3b1..91f0bbb 100644 (file)
@@ -866,6 +866,8 @@ void try_outgoing_connections(void) {
                                node_add(n);
                        }
 
+                       free(name);
+
                        outgoing->node = n;
                        list_insert_tail(outgoing_list, outgoing);
                        setup_outgoing_connection(outgoing, true);
index a270ffc..de3d70d 100644 (file)
@@ -214,6 +214,9 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len)
        environment_add(&env, "REMOTEADDRESS=%s", address);
        environment_add(&env, "NAME=%s", myself->name);
 
+       free(address);
+       free(port);
+
        execute_script("invitation-accepted", &env);
 
        environment_exit(&env);
index 57c4281..ec43469 100644 (file)
@@ -1884,7 +1884,7 @@ static int cmd_config(int argc, char *argv[]) {
        char *node = NULL;
        char *variable;
        char *value;
-       int len;
+       size_t len;
 
        len = strcspn(line, "\t =");
        value = line + len;
index 31d071c..118d011 100644 (file)
@@ -70,15 +70,16 @@ int main(int argc, char *argv[]) {
        int sock[2];
        char buf[1024];
 
-       struct addrinfo *ai, hint;
-       memset(&hint, 0, sizeof(hint));
-
-       hint.ai_family = AF_UNSPEC;
-       hint.ai_socktype = SOCK_STREAM;
-       hint.ai_protocol = IPPROTO_TCP;
-       hint.ai_flags = 0;
+       const struct addrinfo hint = {
+               .ai_family = AF_UNSPEC,
+               .ai_socktype = SOCK_STREAM,
+               .ai_protocol = IPPROTO_TCP,
+               .ai_flags = 0,
+       };
 
        for(int i = 0; i < 2; i++) {
+               struct addrinfo *ai;
+
                if(getaddrinfo(argv[2 + 3 * i], argv[3 + 3 * i], &hint, &ai) || !ai) {
                        fprintf(stderr, "getaddrinfo() failed: %s\n", sockstrerror(sockerrno));
                        return 1;
@@ -88,14 +89,18 @@ int main(int argc, char *argv[]) {
 
                if(sock[i] == -1) {
                        fprintf(stderr, "Could not create socket: %s\n", sockstrerror(sockerrno));
+                       freeaddrinfo(ai);
                        return 1;
                }
 
                if(connect(sock[i], ai->ai_addr, ai->ai_addrlen)) {
                        fprintf(stderr, "Could not connect to %s: %s\n", argv[i + 3 * i], sockstrerror(sockerrno));
+                       freeaddrinfo(ai);
                        return 1;
                }
 
+               freeaddrinfo(ai);
+
                fprintf(stderr, "Connected to %s\n", argv[1 + 3 * i]);
 
                /* Pretend to be the other one */