summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/array.c9
-rw-r--r--common/attrs.c5
-rw-r--r--common/compat.c17
-rw-r--r--common/compat.h8
-rw-r--r--configure.ac1
5 files changed, 36 insertions, 4 deletions
diff --git a/common/array.c b/common/array.c
index 185ea2f..6124475 100644
--- a/common/array.c
+++ b/common/array.c
@@ -49,13 +49,16 @@ maybe_expand_array (p11_array *array,
return true;
- new_allocated = array->allocated * 2;
- if (new_allocated == 0)
+ if (array->allocated == 0)
new_allocated = 16;
+ else {
+ return_val_if_fail (SIZE_MAX / array->allocated >= 2, false);
+ new_allocated = array->allocated * 2;
+ }
if (new_allocated < length)
new_allocated = length;
- new_memory = realloc (array->elem, new_allocated * sizeof (void*));
+ new_memory = reallocarray (array->elem, new_allocated, sizeof (void*));
return_val_if_fail (new_memory != NULL, false);
array->elem = new_memory;
diff --git a/common/attrs.c b/common/attrs.c
index 5a138a8..aa91891 100644
--- a/common/attrs.c
+++ b/common/attrs.c
@@ -101,12 +101,15 @@ attrs_build (CK_ATTRIBUTE *attrs,
CK_ULONG at;
CK_ULONG j;
CK_ULONG i;
+ size_t length;
/* How many attributes we already have */
current = p11_attrs_count (attrs);
/* Reallocate for how many we need */
- attrs = realloc (attrs, (current + count_to_add + 1) * sizeof (CK_ATTRIBUTE));
+ length = current + count_to_add;
+ return_val_if_fail (current <= length && length < SIZE_MAX, NULL);
+ attrs = reallocarray (attrs, length + 1, sizeof (CK_ATTRIBUTE));
return_val_if_fail (attrs != NULL, NULL);
at = current;
diff --git a/common/compat.c b/common/compat.c
index 692e2ca..3114724 100644
--- a/common/compat.c
+++ b/common/compat.c
@@ -487,6 +487,23 @@ strndup (const char *data,
#endif /* HAVE_STRNDUP */
+#ifndef HAVE_REALLOCARRAY
+
+void *
+reallocarray (void *ptr,
+ size_t nmemb,
+ size_t size)
+{
+ assert (nmemb > 0 && size > 0);
+ if (SIZE_MAX / nmemb < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return realloc (ptr, nmemb * size);
+}
+
+#endif /* HAVE_MEMDUP */
+
#ifndef HAVE_STRCONCAT
#include <stdarg.h>
diff --git a/common/compat.h b/common/compat.h
index b021494..a9d2fe1 100644
--- a/common/compat.h
+++ b/common/compat.h
@@ -258,6 +258,14 @@ char * strndup (const char *data,
#endif /* HAVE_STRDUP */
+#ifndef HAVE_REALLOCARRAY
+
+void * reallocarray (void *ptr,
+ size_t nmemb,
+ size_t size);
+
+#endif /* HAVE_REALLOCARRAY */
+
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#else
diff --git a/configure.ac b/configure.ac
index 89e5f99..856a37c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -101,6 +101,7 @@ if test "$os_unix" = "yes"; then
AC_CHECK_FUNCS([getprogname getexecname basename mkstemp mkdtemp])
AC_CHECK_FUNCS([getauxval issetugid getresuid secure_getenv])
AC_CHECK_FUNCS([strnstr memdup strndup strerror_l strerror_r])
+ AC_CHECK_FUNCS([reallocarray])
AC_CHECK_FUNCS([fdwalk])
AC_CHECK_FUNCS([setenv])
AC_CHECK_FUNCS([getpeereid])