From d93d4f9dbd09bc5e53a9b5eeb1cc94939fee32bc Mon Sep 17 00:00:00 2001 From: Kirill Isakov Date: Wed, 27 Apr 2022 00:50:55 +0600 Subject: [PATCH] Improve use of compiler attributes Mark some constructor/destructor pairs, add format attributes where they were missing, and fix new warnings. --- src/address_cache.c | 10 +++++++--- src/address_cache.h | 4 ++-- src/bsd/tunemu.c | 1 + src/chacha-poly1305/chacha-poly1305.h | 2 +- src/cipher.c | 9 ++++----- src/cipher.h | 4 ++-- src/conf.c | 5 ++--- src/conf.h | 6 +++--- src/connection.c | 3 ++- src/connection.h | 4 ++-- src/digest.c | 9 ++++----- src/digest.h | 4 ++-- src/dropin.h | 4 ++-- src/ecdh.h | 4 ++-- src/ecdsa.h | 10 +++++----- src/ecdsagen.h | 2 +- src/ed25519/ecdsa.c | 11 ++++++++--- src/edge.h | 2 +- src/fsck.c | 3 +-- src/have.h | 6 ++++++ src/keys.c | 22 +++++++++------------- src/keys.h | 8 ++++---- src/list.h | 5 +++-- src/meson.build | 9 +++++++++ src/net.h | 2 +- src/net_setup.c | 6 ++++-- src/netutl.h | 2 +- src/node.c | 8 ++++---- src/node.h | 2 +- src/protocol_auth.c | 8 ++++---- src/protocol_key.c | 20 ++++++++++++++------ src/rsa.h | 8 ++++---- src/rsagen.h | 2 +- src/splay_tree.h | 4 ++-- src/subnet.h | 2 +- src/tincctl.c | 3 ++- src/tincctl.h | 3 +-- src/utils.h | 4 ++-- 38 files changed, 125 insertions(+), 96 deletions(-) diff --git a/src/address_cache.c b/src/address_cache.c index a414f46f..d9996fb0 100644 --- a/src/address_cache.c +++ b/src/address_cache.c @@ -213,7 +213,9 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) { } // We're all out of addresses. - exit_configuration(&cache->config_tree); + exit_configuration(cache->config_tree); + cache->config_tree = NULL; + return false; } @@ -255,7 +257,8 @@ void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) { } if(cache->config_tree) { - exit_configuration(&cache->config_tree); + exit_configuration(cache->config_tree); + cache->config_tree = NULL; } if(cache->ai) { @@ -271,7 +274,8 @@ void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) { void close_address_cache(address_cache_t *cache) { if(cache->config_tree) { - exit_configuration(&cache->config_tree); + exit_configuration(cache->config_tree); + cache->config_tree = NULL; } if(cache->ai) { diff --git a/src/address_cache.h b/src/address_cache.h index 4ce6ec5e..1f891c96 100644 --- a/src/address_cache.h +++ b/src/address_cache.h @@ -43,8 +43,8 @@ typedef struct address_cache_t { void add_recent_address(address_cache_t *cache, const sockaddr_t *sa); const sockaddr_t *get_recent_address(address_cache_t *cache); -address_cache_t *open_address_cache(struct node_t *node); -void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa); void close_address_cache(address_cache_t *cache); +address_cache_t *open_address_cache(node_t *node) ATTR_DEALLOCATOR(close_address_cache); +void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa); #endif diff --git a/src/bsd/tunemu.c b/src/bsd/tunemu.c index 6867c47b..4e3fbc7d 100644 --- a/src/bsd/tunemu.c +++ b/src/bsd/tunemu.c @@ -80,6 +80,7 @@ static pcap_t *pcap = NULL; static size_t data_buffer_length = 0; static uint8_t *data_buffer = NULL; +static void tun_error(char *format, ...) ATTR_FORMAT(printf, 1, 2); static void tun_error(char *format, ...) { va_list vl; va_start(vl, format); diff --git a/src/chacha-poly1305/chacha-poly1305.h b/src/chacha-poly1305/chacha-poly1305.h index b558e450..e75d984f 100644 --- a/src/chacha-poly1305/chacha-poly1305.h +++ b/src/chacha-poly1305/chacha-poly1305.h @@ -5,8 +5,8 @@ typedef struct chacha_poly1305_ctx chacha_poly1305_ctx_t; -extern chacha_poly1305_ctx_t *chacha_poly1305_init(void); extern void chacha_poly1305_exit(chacha_poly1305_ctx_t *); +extern chacha_poly1305_ctx_t *chacha_poly1305_init(void) ATTR_DEALLOCATOR(chacha_poly1305_exit); extern bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const uint8_t *key); extern bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen); diff --git a/src/cipher.c b/src/cipher.c index 5ac790a1..4e4fb9c9 100644 --- a/src/cipher.c +++ b/src/cipher.c @@ -28,11 +28,10 @@ cipher_t *cipher_alloc(void) { return xzalloc(sizeof(cipher_t)); } -void cipher_free(cipher_t **cipher) { - if(cipher && *cipher) { - cipher_close(*cipher); - free(*cipher); - *cipher = NULL; +void cipher_free(cipher_t *cipher) { + if(cipher) { + cipher_close(cipher); + free(cipher); } } diff --git a/src/cipher.h b/src/cipher.h index 7911455d..116a0312 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -36,8 +36,8 @@ #error Incorrect cryptographic library, please reconfigure. #endif -extern cipher_t *cipher_alloc(void) ATTR_MALLOC; -extern void cipher_free(cipher_t **cipher); +extern void cipher_free(cipher_t *cipher); +extern cipher_t *cipher_alloc(void) ATTR_MALLOC ATTR_DEALLOCATOR(cipher_free); extern bool cipher_open_by_name(cipher_t *cipher, const char *name); extern bool cipher_open_by_nid(cipher_t *cipher, nid_t nid); extern void cipher_close(cipher_t *cipher); diff --git a/src/conf.c b/src/conf.c index c8cb1414..d4c76ec8 100644 --- a/src/conf.c +++ b/src/conf.c @@ -87,9 +87,8 @@ void init_configuration(splay_tree_t *tree) { tree->delete = (splay_action_t) free_config; } -void exit_configuration(splay_tree_t **config_tree) { - splay_delete_tree(*config_tree); - *config_tree = NULL; +void exit_configuration(splay_tree_t *config_tree) { + splay_delete_tree(config_tree); } config_t *new_config(void) { diff --git a/src/conf.h b/src/conf.h index 3cf677d5..d01a237c 100644 --- a/src/conf.h +++ b/src/conf.h @@ -40,11 +40,11 @@ extern int maxtimeout; extern bool bypass_security; extern list_t cmdline_conf; -extern splay_tree_t *create_configuration(void); +extern void exit_configuration(splay_tree_t *config_tree); +extern splay_tree_t *create_configuration(void) ATTR_MALLOC ATTR_DEALLOCATOR(exit_configuration); extern void init_configuration(splay_tree_t *); -extern void exit_configuration(splay_tree_t **config_tree); -extern config_t *new_config(void) ATTR_MALLOC; extern void free_config(config_t *config); +extern config_t *new_config(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_config); extern void config_add(splay_tree_t *config_tree, config_t *config); extern config_t *lookup_config(splay_tree_t *config_tree, const char *variable); extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config); diff --git a/src/connection.c b/src/connection.c index 533e0245..4f8d4fd7 100644 --- a/src/connection.c +++ b/src/connection.c @@ -148,7 +148,8 @@ void free_connection(connection_t *c) { free(c->hostname); if(c->config_tree) { - exit_configuration(&c->config_tree); + exit_configuration(c->config_tree); + c->config_tree = NULL; } free(c); diff --git a/src/connection.h b/src/connection.h index 23bde776..600c9542 100644 --- a/src/connection.h +++ b/src/connection.h @@ -79,7 +79,7 @@ typedef struct legacy_ctx_t { legacy_crypto_t out; /* cipher/digest we will use to send data to him */ } legacy_ctx_t; -legacy_ctx_t *new_legacy_ctx(rsa_t *rsa) ATTR_MALLOC; +legacy_ctx_t *new_legacy_ctx(rsa_t *rsa); void free_legacy_ctx(legacy_ctx_t *ctx); #endif @@ -131,8 +131,8 @@ extern connection_t *everyone; extern void init_connections(void); extern void exit_connections(void); -extern connection_t *new_connection(void) ATTR_MALLOC; extern void free_connection(connection_t *c); +extern connection_t *new_connection(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_connection); extern void connection_add(connection_t *c); extern void connection_del(connection_t *c); extern bool dump_connections(struct connection_t *c); diff --git a/src/digest.c b/src/digest.c index 4ef98cd8..15a111a9 100644 --- a/src/digest.c +++ b/src/digest.c @@ -28,11 +28,10 @@ digest_t *digest_alloc(void) { return xzalloc(sizeof(digest_t)); } -void digest_free(digest_t **digest) { - if(digest && *digest) { - digest_close(*digest); - free(*digest); - *digest = NULL; +void digest_free(digest_t *digest) { + if(digest) { + digest_close(digest); + free(digest); } } diff --git a/src/digest.h b/src/digest.h index fdb1be25..08c5141a 100644 --- a/src/digest.h +++ b/src/digest.h @@ -39,8 +39,8 @@ typedef struct digest digest_t; extern bool digest_open_by_name(digest_t *digest, const char *name, size_t maclength); extern bool digest_open_by_nid(digest_t *digest, nid_t nid, size_t maclength); -extern digest_t *digest_alloc(void) ATTR_MALLOC; -extern void digest_free(digest_t **digest); +extern void digest_free(digest_t *digest); +extern digest_t *digest_alloc(void) ATTR_MALLOC ATTR_DEALLOCATOR(digest_free); extern void digest_close(digest_t *digest); extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) ATTR_WARN_UNUSED; extern bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *digestdata) ATTR_WARN_UNUSED; diff --git a/src/dropin.h b/src/dropin.h index f020f215..6fa7a9dd 100644 --- a/src/dropin.h +++ b/src/dropin.h @@ -26,8 +26,8 @@ extern int daemon(int, int); #endif #ifndef HAVE_ASPRINTF -extern int asprintf(char **, const char *, ...); -extern int vasprintf(char **, const char *, va_list ap); +extern int asprintf(char **, const char *, ...) ATTR_FORMAT(printf, 2, 3); +extern int vasprintf(char **, const char *, va_list ap) ATTR_FORMAT(printf, 2, 0); #endif #ifndef HAVE_GETTIMEOFDAY diff --git a/src/ecdh.h b/src/ecdh.h index 4cd8586f..98ddb719 100644 --- a/src/ecdh.h +++ b/src/ecdh.h @@ -29,8 +29,8 @@ typedef struct ecdh ecdh_t; #endif -extern ecdh_t *ecdh_generate_public(void *pubkey) ATTR_MALLOC; -extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) ATTR_WARN_UNUSED; extern void ecdh_free(ecdh_t *ecdh); +extern ecdh_t *ecdh_generate_public(void *pubkey) ATTR_MALLOC ATTR_DEALLOCATOR(ecdh_free); +extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) ATTR_WARN_UNUSED; #endif diff --git a/src/ecdsa.h b/src/ecdsa.h index 659d5596..44e2ff8a 100644 --- a/src/ecdsa.h +++ b/src/ecdsa.h @@ -26,14 +26,14 @@ typedef struct ecdsa ecdsa_t; #endif -extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) ATTR_MALLOC; -extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); -extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) ATTR_MALLOC; -extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) ATTR_MALLOC; +extern void ecdsa_free(ecdsa_t *ecdsa); +extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); +extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); +extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); +extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) ATTR_MALLOC; extern size_t ecdsa_size(ecdsa_t *ecdsa); extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) ATTR_WARN_UNUSED; extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) ATTR_WARN_UNUSED; extern bool ecdsa_active(ecdsa_t *ecdsa); -extern void ecdsa_free(ecdsa_t *ecdsa); #endif diff --git a/src/ecdsagen.h b/src/ecdsagen.h index 1132dd6f..c3ba0d55 100644 --- a/src/ecdsagen.h +++ b/src/ecdsagen.h @@ -22,7 +22,7 @@ #include "ecdsa.h" -extern ecdsa_t *ecdsa_generate(void) ATTR_MALLOC; +extern ecdsa_t *ecdsa_generate(void) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) ATTR_WARN_UNUSED; extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) ATTR_WARN_UNUSED; diff --git a/src/ed25519/ecdsa.c b/src/ed25519/ecdsa.c index 28daf4a1..1ba01cfa 100644 --- a/src/ed25519/ecdsa.c +++ b/src/ed25519/ecdsa.c @@ -32,6 +32,11 @@ typedef struct { #include "../utils.h" #include "../xalloc.h" +static ecdsa_t *ecdsa_new(void) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); +static ecdsa_t *ecdsa_new(void) { + return xzalloc(sizeof(ecdsa_t)); +} + // Get and set ECDSA keys // ecdsa_t *ecdsa_set_base64_public_key(const char *p) { @@ -42,7 +47,7 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) { return 0; } - ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); + ecdsa_t *ecdsa = ecdsa_new(); len = b64decode_tinc(p, ecdsa->public, len); if(len != 32) { @@ -123,7 +128,7 @@ exit: } ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa)); + ecdsa_t *ecdsa = ecdsa_new(); if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) { return ecdsa; @@ -134,7 +139,7 @@ ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { } ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa)); + ecdsa_t *ecdsa = ecdsa_new(); if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) { return ecdsa; diff --git a/src/edge.h b/src/edge.h index 3430eb12..3b4dbb20 100644 --- a/src/edge.h +++ b/src/edge.h @@ -42,8 +42,8 @@ typedef struct edge_t { extern splay_tree_t edge_weight_tree; /* Tree with all known edges sorted on weight */ extern void exit_edges(void); -extern edge_t *new_edge(void) ATTR_MALLOC; extern void free_edge(edge_t *e); +extern edge_t *new_edge(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_edge); extern void init_edge_tree(splay_tree_t *tree); extern void edge_add(edge_t *e); extern void edge_del(edge_t *e); diff --git a/src/fsck.c b/src/fsck.c index 28da620e..8d818a3c 100644 --- a/src/fsck.c +++ b/src/fsck.c @@ -536,8 +536,7 @@ static bool check_public_keys(splay_tree_t *config, const char *name, rsa_t *rsa fprintf(stderr, "WARNING: cannot read %s\n", host_file); } - ecdsa_t *ec_pub = NULL; - read_ecdsa_public_key(&ec_pub, &config, name); + ecdsa_t *ec_pub = read_ecdsa_public_key(&config, name); bool success = true; #ifndef DISABLE_LEGACY diff --git a/src/have.h b/src/have.h index d176098f..a155b04b 100644 --- a/src/have.h +++ b/src/have.h @@ -63,6 +63,12 @@ #endif #endif +#if defined(HAVE_ATTR_MALLOC_WITH_ARG) +#define ATTR_DEALLOCATOR(dealloc) __attribute__((__malloc__(dealloc))) +#else +#define ATTR_DEALLOCATOR(dealloc) +#endif + #ifdef HAVE_ATTR_MALLOC #define ATTR_MALLOC __attribute__((__malloc__)) #else diff --git a/src/keys.c b/src/keys.c index 84bd0719..5fe51ae6 100644 --- a/src/keys.c +++ b/src/keys.c @@ -162,11 +162,7 @@ ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile) { return key; } -bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const char *name) { - if(ecdsa_active(*ecdsa)) { - return true; - } - +ecdsa_t *read_ecdsa_public_key(splay_tree_t **config_tree, const char *name) { FILE *fp; char *fname; char *p; @@ -175,16 +171,16 @@ bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const ch *config_tree = create_configuration(); if(!read_host_config(*config_tree, name, true)) { - return false; + return NULL; } } /* First, check for simple Ed25519PublicKey statement */ if(get_config_string(lookup_config(*config_tree, "Ed25519PublicKey"), &p)) { - *ecdsa = ecdsa_set_base64_public_key(p); + ecdsa_t *ecdsa = ecdsa_set_base64_public_key(p); free(p); - return *ecdsa != NULL; + return ecdsa; } /* Else, check for Ed25519PublicKeyFile statement and read it */ @@ -199,19 +195,19 @@ bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const ch logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s", fname, strerror(errno)); free(fname); - return false; + return NULL; } - *ecdsa = ecdsa_read_pem_public_key(fp); + ecdsa_t *ecdsa = ecdsa_read_pem_public_key(fp); - if(!*ecdsa && errno != ENOENT) { + if(!ecdsa && errno != ENOENT) { logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname); } fclose(fp); free(fname); - return *ecdsa != NULL; + return ecdsa; } #ifndef DISABLE_LEGACY @@ -321,7 +317,7 @@ rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name) { if(!fp) { logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno)); free(fname); - return false; + return NULL; } rsa_t *rsa = rsa_read_pem_public_key(fp); diff --git a/src/keys.h b/src/keys.h index 1e0dc157..d7ab3382 100644 --- a/src/keys.h +++ b/src/keys.h @@ -7,12 +7,12 @@ extern bool disable_old_keys(const char *filename, const char *what); -extern ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile); -extern bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const char *name); +extern ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); +extern ecdsa_t *read_ecdsa_public_key(splay_tree_t **config_tree, const char *name) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); #ifndef DISABLE_LEGACY -extern rsa_t *read_rsa_private_key(splay_tree_t *config, char **keyfile); -extern rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name); +extern rsa_t *read_rsa_private_key(splay_tree_t *config, char **keyfile) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free); +extern rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free); #endif #endif // TINC_KEYS_H diff --git a/src/list.h b/src/list.h index e605ce10..8bd2f168 100644 --- a/src/list.h +++ b/src/list.h @@ -45,10 +45,11 @@ typedef struct list_t { /* (De)constructors */ -extern list_t *list_alloc(list_action_t delete) ATTR_MALLOC; extern void list_free(list_t *list); -extern list_node_t *list_alloc_node(void); +extern list_t *list_alloc(list_action_t delete) ATTR_MALLOC ATTR_DEALLOCATOR(list_free); + extern void list_free_node(list_t *list, list_node_t *node); +extern list_node_t *list_alloc_node(void) ATTR_MALLOC ATTR_DEALLOCATOR(list_free_node); /* Insertion and deletion */ diff --git a/src/meson.build b/src/meson.build index e8c3e53f..1d195cfa 100644 --- a/src/meson.build +++ b/src/meson.build @@ -18,6 +18,15 @@ foreach attr : ['malloc', 'nonnull', 'warn_unused_result', 'packed', 'format'] endif endforeach +if cc.compiles(''' + #include + extern void *make() __attribute__((malloc(free))); + int main(void) { return 0; } +''') + cdata.set('HAVE_ATTR_MALLOC_WITH_ARG', 1, + description: 'support for __attribute__((malloc(deallocator)))') +endif + if cc.compiles(''' _Static_assert(1, "ok"); int main(void) { return 0; } diff --git a/src/net.h b/src/net.h index 8e256ce7..888a70c2 100644 --- a/src/net.h +++ b/src/net.h @@ -199,7 +199,7 @@ extern void send_packet(struct node_t *n, vpn_packet_t *packet); extern void receive_tcppacket(struct connection_t *c, const char *buffer, size_t length); extern bool receive_tcppacket_sptps(struct connection_t *c, const char *buffer, size_t length); extern void broadcast_packet(const struct node_t *n, vpn_packet_t *packet); -extern char *get_name(void); +extern char *get_name(void) ATTR_MALLOC; extern void device_enable(void); extern void device_disable(void); extern bool setup_myself_reloadable(void); diff --git a/src/net_setup.c b/src/net_setup.c index 40cdaf6c..03186134 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -903,7 +903,8 @@ static bool setup_myself(void) { if(!cipher_open_by_name(myself->incipher, cipher)) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!"); - cipher_free(&myself->incipher); + cipher_free(myself->incipher); + myself->incipher = NULL; free(cipher); return false; } @@ -938,7 +939,8 @@ static bool setup_myself(void) { if(!digest_open_by_name(myself->indigest, digest, maclength)) { logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!"); - digest_free(&myself->indigest); + digest_free(myself->indigest); + myself->indigest = NULL; free(digest); return false; } diff --git a/src/netutl.h b/src/netutl.h index a1ab660a..32181229 100644 --- a/src/netutl.h +++ b/src/netutl.h @@ -27,7 +27,7 @@ extern bool hostnames; // Converts service name (as listed in /etc/services) to port number. Returns 0 on error. extern uint16_t service_to_port(const char *service); -extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) ATTR_MALLOC; +extern struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) ATTR_DEALLOCATOR(freeaddrinfo); extern sockaddr_t str2sockaddr(const char *address, const char *port); extern void sockaddr2str(const sockaddr_t *sa, char **address, char **port); extern char *sockaddr2hostname(const sockaddr_t *sa) ATTR_MALLOC; diff --git a/src/node.c b/src/node.c index 23a06101..8e0f162e 100644 --- a/src/node.c +++ b/src/node.c @@ -99,10 +99,10 @@ void free_node(node_t *n) { sockaddrfree(&n->address); #ifndef DISABLE_LEGACY - cipher_free(&n->incipher); - digest_free(&n->indigest); - cipher_free(&n->outcipher); - digest_free(&n->outdigest); + cipher_free(n->incipher); + digest_free(n->indigest); + cipher_free(n->outcipher); + digest_free(n->outdigest); #endif ecdsa_free(n->ecdsa); diff --git a/src/node.h b/src/node.h index 1e877ab6..fea90d1b 100644 --- a/src/node.h +++ b/src/node.h @@ -121,8 +121,8 @@ extern struct node_t *myself; extern splay_tree_t node_tree; extern void exit_nodes(void); -extern node_t *new_node(void) ATTR_MALLOC; extern void free_node(node_t *n); +extern node_t *new_node(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_node); extern void node_add(node_t *n); extern void node_del(node_t *n); extern node_t *lookup_node(char *name); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 211d9083..d7cbbd48 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -94,7 +94,7 @@ bool send_id(connection_t *c) { int minor = 0; if(experimental) { - if(c->outgoing && !read_ecdsa_public_key(&c->ecdsa, &c->config_tree, c->name)) { + if(c->outgoing && !ecdsa_active(c->ecdsa) && !(c->ecdsa = read_ecdsa_public_key(&c->config_tree, c->name))) { minor = 1; } else { minor = myself->connection->protocol_minor; @@ -399,8 +399,8 @@ bool id_h(connection_t *c, const char *request) { return false; } - if(experimental) { - read_ecdsa_public_key(&c->ecdsa, &c->config_tree, c->name); + if(experimental && !ecdsa_active(c->ecdsa)) { + c->ecdsa = read_ecdsa_public_key(&c->config_tree, c->name); } /* Ignore failures if no key known yet */ @@ -880,7 +880,7 @@ static bool upgrade_h(connection_t *c, const char *request) { return false; } - if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(&c->ecdsa, &c->config_tree, c->name)) { + if(ecdsa_active(c->ecdsa) || (c->ecdsa = read_ecdsa_public_key(&c->config_tree, c->name))) { char *knownkey = ecdsa_get_base64_public_key(c->ecdsa); bool different = strcmp(knownkey, pubkey); free(knownkey); diff --git a/src/protocol_key.c b/src/protocol_key.c index 09acd6a9..0890755e 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -346,8 +346,11 @@ bool send_ans_key(node_t *to) { randomize(key, keylen); - cipher_free(&to->incipher); - digest_free(&to->indigest); + cipher_free(to->incipher); + to->incipher = NULL; + + digest_free(to->indigest); + to->indigest = NULL; if(myself->incipher) { to->incipher = cipher_alloc(); @@ -470,8 +473,11 @@ bool ans_key_h(connection_t *c, const char *request) { #ifndef DISABLE_LEGACY /* Don't use key material until every check has passed. */ - cipher_free(&from->outcipher); - digest_free(&from->outdigest); + cipher_free(from->outcipher); + from->outcipher = NULL; + + digest_free(from->outdigest); + from->outdigest = NULL; #endif if(!from->status.sptps) { @@ -570,7 +576,8 @@ bool ans_key_h(connection_t *c, const char *request) { from->outcipher = cipher_alloc(); if(!cipher_open_by_nid(from->outcipher, cipher)) { - cipher_free(&from->outcipher); + cipher_free(from->outcipher); + from->outcipher = NULL; logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); return false; } @@ -582,7 +589,8 @@ bool ans_key_h(connection_t *c, const char *request) { from->outdigest = digest_alloc(); if(!digest_open_by_nid(from->outdigest, digest, maclength)) { - digest_free(&from->outdigest); + digest_free(from->outdigest); + from->outdigest = NULL; logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); return false; } diff --git a/src/rsa.h b/src/rsa.h index 8f0c1f68..3cc1e21a 100644 --- a/src/rsa.h +++ b/src/rsa.h @@ -27,10 +27,10 @@ typedef struct rsa rsa_t; #endif extern void rsa_free(rsa_t *rsa); -extern rsa_t *rsa_set_hex_public_key(const char *n, const char *e) ATTR_MALLOC; -extern rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) ATTR_MALLOC; -extern rsa_t *rsa_read_pem_public_key(FILE *fp) ATTR_MALLOC; -extern rsa_t *rsa_read_pem_private_key(FILE *fp) ATTR_MALLOC; +extern rsa_t *rsa_set_hex_public_key(const char *n, const char *e) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free); +extern rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free); +extern rsa_t *rsa_read_pem_public_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free); +extern rsa_t *rsa_read_pem_private_key(FILE *fp) ATTR_MALLOC ATTR_DEALLOCATOR(rsa_free); extern size_t rsa_size(const rsa_t *rsa); extern bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) ATTR_WARN_UNUSED; extern bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) ATTR_WARN_UNUSED; diff --git a/src/rsagen.h b/src/rsagen.h index 795153d5..27c076d0 100644 --- a/src/rsagen.h +++ b/src/rsagen.h @@ -22,7 +22,7 @@ #include "rsa.h" -extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) ATTR_MALLOC; +extern rsa_t *rsa_generate(size_t bits, unsigned long exponent) ATTR_DEALLOCATOR(rsa_free); extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) ATTR_WARN_UNUSED; extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) ATTR_WARN_UNUSED; diff --git a/src/splay_tree.h b/src/splay_tree.h index 24645fa5..d61b5b00 100644 --- a/src/splay_tree.h +++ b/src/splay_tree.h @@ -63,11 +63,11 @@ typedef struct splay_tree_t { /* (De)constructors */ -extern splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) ATTR_MALLOC; extern void splay_free_tree(splay_tree_t *tree); +extern splay_tree_t *splay_alloc_tree(splay_compare_t compare, splay_action_t delete) ATTR_MALLOC ATTR_DEALLOCATOR(splay_free_tree); -extern splay_node_t *splay_alloc_node(void) ATTR_MALLOC; extern void splay_free_node(splay_tree_t *tree, splay_node_t *node); +extern splay_node_t *splay_alloc_node(void) ATTR_MALLOC ATTR_DEALLOCATOR(splay_free_node); /* Insertion and deletion */ diff --git a/src/subnet.h b/src/subnet.h index 016aa547..6220e580 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -65,8 +65,8 @@ typedef struct subnet_t { extern splay_tree_t subnet_tree; extern int subnet_compare(const struct subnet_t *a, const struct subnet_t *b); -extern subnet_t *new_subnet(void) ATTR_MALLOC; extern void free_subnet(subnet_t *subnet); +extern subnet_t *new_subnet(void) ATTR_MALLOC ATTR_DEALLOCATOR(free_subnet); extern void init_subnets(void); extern void exit_subnets(void); extern void init_subnet_tree(splay_tree_t *tree); diff --git a/src/tincctl.c b/src/tincctl.c index a18f6ce6..b2d98f62 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -1623,7 +1623,8 @@ char *get_my_name(bool verbose) { return NULL; } -ecdsa_t *get_pubkey(FILE *f) { +static ecdsa_t *get_pubkey(FILE *f) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free); +static ecdsa_t *get_pubkey(FILE *f) { char buf[4096]; char *value; diff --git a/src/tincctl.h b/src/tincctl.h index 4018bb32..9bacc46a 100644 --- a/src/tincctl.h +++ b/src/tincctl.h @@ -47,11 +47,10 @@ typedef struct { extern const var_t variables[]; extern size_t rstrip(char *value); -extern char *get_my_name(bool verbose); +extern char *get_my_name(bool verbose) ATTR_MALLOC; extern bool connect_tincd(bool verbose); extern bool sendline(int fd, const char *format, ...); extern bool recvline(int fd, char *line, size_t len); extern int check_port(const char *name); -extern ecdsa_t *get_pubkey(FILE *f); #endif diff --git a/src/utils.h b/src/utils.h index bd5ce13c..f02bb9f2 100644 --- a/src/utils.h +++ b/src/utils.h @@ -72,10 +72,10 @@ static inline suseconds_t jitter(void) { extern bool check_id(const char *id); extern bool check_netname(const char *netname, bool strict); -char *replace_name(const char *name); +char *replace_name(const char *name) ATTR_MALLOC; char *absolute_path(const char *path) ATTR_MALLOC; -extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms); +extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms) ATTR_DEALLOCATOR(fclose); #endif -- 2.20.1