libmapper: fix logic bug
sarraylen returns the number of strings and does not include the
trailing null pointer. This results in sarraydup creating arrays of
strings where the array is not null pointer terminated (the strings
themselves _are_ \0 terminated), which in turn causes random data to be
passed to free.
The bug was found using static analysis and inspection would indicate
exposure only exists on error and shutdown paths, which might be a hint
as to how this has been lurking for as long as it has.
Change-Id: Ie5e5b6cdfb7832c84037ff039b41082fc7d20b61
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/libmapper/mapper.c b/libmapper/mapper.c
index fb07940..4a1cd3b 100644
--- a/libmapper/mapper.c
+++ b/libmapper/mapper.c
@@ -27,6 +27,8 @@
#include <systemd/sd-event.h>
#include <unistd.h>
+#include "internal.h"
+
#define _public_ __attribute__((__visibility__("default")))
static const char* async_wait_introspection_match =
@@ -99,7 +101,7 @@
static int async_subtree_getpaths_callback(sd_bus_message*, void*,
sd_bus_error*);
-static int sarraylen(char* array[])
+int sarraylen(char* array[])
{
int count = 0;
char** p = array;
@@ -113,7 +115,7 @@
return count;
}
-static void sarrayfree(char* array[])
+void sarrayfree(char* array[])
{
char** p = array;
while (*p != NULL)
@@ -124,13 +126,13 @@
free(array);
}
-static char** sarraydup(char* array[])
+char** sarraydup(char* array[])
{
int count = sarraylen(array);
int i;
char** ret = NULL;
- ret = malloc(sizeof(*ret) * count);
+ ret = calloc(count + 1, sizeof(*ret));
if (!ret)
return NULL;