From 9e8082294a3509b66d98f7340283d0d2bedfa5be Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 29 Jul 2014 16:57:09 +0200 Subject: [PATCH] Check all arguments of the public API for NULL pointers. --- src/meshlink++.h | 5 ++-- src/meshlink.c | 59 ++++++++++++++++++++++++++++++++++++++++++++---- src/meshlink.h | 5 ++-- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/meshlink++.h b/src/meshlink++.h index a357cca6..2729130c 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -182,9 +182,10 @@ namespace meshlink { * @param nodes A pointer to an array of pointers to meshlink::node, which should be allocated by the application. * @param nmemb The maximum number of pointers that can be stored in the nodes array. * - * @return The number of known nodes. This can be larger than nmemb, in which case not all nodes were stored in the nodes array. + * @return The number of known nodes, or -1 in case of an error. + * This can be larger than nmemb, in which case not all nodes were stored in the nodes array. */ - size_t get_all_nodes(node **nodes, size_t nmemb) { + ssize_t get_all_nodes(node **nodes, size_t nmemb) { return meshlink_get_all_nodes(this, (meshlink_node_t **)nodes, nmemb); } diff --git a/src/meshlink.c b/src/meshlink.c index f173c8d2..b3e87faa 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -800,6 +800,9 @@ static void *meshlink_main_loop(void *arg) { } bool meshlink_start(meshlink_handle_t *mesh) { + if(!mesh) + return false; + // TODO: open listening sockets first //Check that a valid name is set @@ -822,6 +825,9 @@ bool meshlink_start(meshlink_handle_t *mesh) { } void meshlink_stop(meshlink_handle_t *mesh) { + if(!mesh) + return; + // Shut down the listening sockets to signal the main thread to shut down for(int i = 0; i < mesh->listen_sockets; i++) { @@ -835,6 +841,9 @@ void meshlink_stop(meshlink_handle_t *mesh) { } void meshlink_close(meshlink_handle_t *mesh) { + if(!mesh) + return; + // Close and free all resources used. close_network_connections(mesh); @@ -852,19 +861,31 @@ void meshlink_close(meshlink_handle_t *mesh) { } void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) { + if(!mesh) + return; mesh->receive_cb = cb; } void meshlink_set_node_status_cb(meshlink_handle_t *mesh, meshlink_node_status_cb_t cb) { + if(!mesh) + return; mesh->node_status_cb = cb; } void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, meshlink_log_cb_t cb) { + if(!mesh) + return; mesh->log_cb = cb; mesh->log_level = level; } bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, unsigned int len) { + if(!mesh || !destination) + return false; + if(!len) + return true; + if(!data) + return false; /* If there is no outgoing list yet, create one. */ @@ -914,10 +935,15 @@ void meshlink_send_from_queue(event_loop_t* el,meshlink_handle_t *mesh) { } meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) { + if(!mesh || !name) + return NULL; return (meshlink_node_t *)lookup_node(mesh, (char *)name); // TODO: make lookup_node() use const } -size_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t nmemb) { +ssize_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t nmemb) { + if(!mesh || (nmemb && !nodes)) + return -1; + size_t i = 0; //lock mesh->nodes @@ -935,6 +961,8 @@ size_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, } bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void *signature, size_t *siglen) { + if(!mesh || !data || !len || !signature || !siglen) + return false; if(*siglen < MESHLINK_SIGLEN) return false; if(!ecdsa_sign(mesh->self->connection->ecdsa, data, len, signature)) @@ -944,6 +972,8 @@ bool meshlink_sign(meshlink_handle_t *mesh, const void *data, size_t len, void * } bool meshlink_verify(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len, const void *signature, size_t siglen) { + if(!mesh || !data || !len || !signature) + return false; if(siglen != MESHLINK_SIGLEN) return false; struct node_t *n = (struct node_t *)source; @@ -1045,6 +1075,9 @@ static bool refresh_invitation_key(meshlink_handle_t *mesh) { } bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) { + if(!mesh || !address) + return false; + for(const char *p = address; *p; p++) { if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':') continue; @@ -1056,6 +1089,9 @@ bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) { } char *meshlink_invite(meshlink_handle_t *mesh, const char *name) { + if(!mesh) + return false; + // Check validity of the new node's name if(!check_id(name)) { fprintf(stderr, "Invalid name for node.\n"); @@ -1222,15 +1258,19 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { mesh->sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(mesh->sock <= 0) { fprintf(stderr, "Could not open socket: %s\n", strerror(errno)); + freeaddrinfo(ai); return false; } if(connect(mesh->sock, ai->ai_addr, ai->ai_addrlen)) { fprintf(stderr, "Could not connect to %s port %s: %s\n", address, port, strerror(errno)); closesocket(mesh->sock); + freeaddrinfo(ai); return false; } + freeaddrinfo(ai); + fprintf(stderr, "Connected to %s port %s...\n", address, port); // Tell him we have an invitation, and give him our throw-away key. @@ -1311,6 +1351,9 @@ invalid: } char *meshlink_export(meshlink_handle_t *mesh) { + if(!mesh) + return NULL; + char filename[PATH_MAX]; snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->self->name); FILE *f = fopen(filename, "r"); @@ -1338,6 +1381,9 @@ char *meshlink_export(meshlink_handle_t *mesh) { } bool meshlink_import(meshlink_handle_t *mesh, const char *data) { + if(!mesh || !data) + return false; + if(strncmp(data, "Name = ", 7)) { fprintf(stderr, "Invalid data\n"); return false; @@ -1385,15 +1431,18 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) { } void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) { - node_t *n; - n = (node_t*)node; - n->status.blacklisted=true; + if(!mesh || !node) + return; + + node_t *n; + n = (node_t*)node; + n->status.blacklisted=true; fprintf(stderr, "Blacklisted %s.\n",node->name); //Make blacklisting persistent in the config file append_config_file(mesh, n->name, "blacklisted", "yes"); - return; + return; } static void __attribute__((constructor)) meshlink_init(void) { diff --git a/src/meshlink.h b/src/meshlink.h index 018ba9a3..e06a5906 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -221,9 +221,10 @@ extern meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *n * @param nodes A pointer to an array of pointers to meshlink_node_t, which should be allocated by the application. * @param nmemb The maximum number of pointers that can be stored in the nodes array. * - * @return The number of known nodes. This can be larger than nmemb, in which case not all nodes were stored in the nodes array. + * @return The number of known nodes, or -1 in case of an error. + * The returned number of nodes can be larger than nmemb, in which case not all nodes were stored in the nodes array. */ -extern size_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t nmemb); +extern ssize_t meshlink_get_all_nodes(meshlink_handle_t *mesh, meshlink_node_t **nodes, size_t nmemb); /// Sign data using the local node's MeshLink key. /** This function signs data using the local node's MeshLink key. -- 2.39.2