[PATCH 2/2] Replace xrealloc with xreallocarray

Masatake YAMATO yamato at redhat.com
Wed Mar 25 17:32:34 UTC 2015


This patch introduces reallocarray, and xreallocarray; and
replaces xrealloc with xreallocarray.

reallocarray is safer version of realloc developed at OpenBSD.
xreallocarray calls reallocarray internally and calls
die_out_of_memory if reallocarray returns NULL, as xmalloc does.

* strace.c (reallocarray, xreallocarray): New functions.
(xrealloc): Remove the implementation.
(expand_tcbtab): Use xreallocarray instead of
xrealloc.
* pathtrace.c (storepath): Use xreallocarray instead of
xrealloc.
* syscall.c (reallocate_qual): Ditto.
* unwind.c (build_mmap_cache): Ditto.
(get_symbol_name): Ditto.
* defs.h (xrealloc): Remove the declaration.
(xreallocarray): New declaration.

Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
 defs.h      |  2 +-
 pathtrace.c |  2 +-
 strace.c    | 44 +++++++++++++++++++++++++++++++++++++++++---
 syscall.c   |  2 +-
 unwind.c    |  6 +++---
 5 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/defs.h b/defs.h
index afc1247..a3a1007 100644
--- a/defs.h
+++ b/defs.h
@@ -403,7 +403,7 @@ void die_out_of_memory(void) __attribute__ ((noreturn));
  */
 void *xmalloc(size_t size);
 void *xcalloc(size_t nmmeb, size_t size);
-void *xrealloc(void *ptr, size_t size);
+void *xreallocarray(void *optr, size_t nmemb, size_t size);
 
 #if USE_CUSTOM_PRINTF
 /*
diff --git a/pathtrace.c b/pathtrace.c
index a70e8b0..2ec91de 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -91,7 +91,7 @@ storepath(const char *path)
 		return; /* already in table */
 
 	i = num_selected++;
-	paths_selected = xrealloc(paths_selected, num_selected * sizeof(paths_selected[0]));
+	paths_selected = xreallocarray(paths_selected, num_selected, sizeof(paths_selected[0]));
 	paths_selected[i] = path;
 }
 
diff --git a/strace.c b/strace.c
index c766da2..f544c97 100644
--- a/strace.c
+++ b/strace.c
@@ -349,9 +349,47 @@ void *xcalloc(size_t nmmeb, size_t size)
 	return r;
 }
 
-void *xrealloc(void *ptr, size_t size)
+
+/* About reallocarray
+ *
+ * Copyright (c) 2008 Otto Moerbeek <otto at drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
+
+static void *
+reallocarray(void *optr, size_t nmemb, size_t size)
 {
-	void *r= realloc(ptr, size);
+	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    nmemb > 0 && SIZE_MAX / nmemb < size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	return realloc(optr, size * nmemb);
+}
+
+void *
+xreallocarray(void *optr, size_t nmemb, size_t size)
+{
+	void *r;
+
+	r = reallocarray(optr, nmemb, size);
 	if (!r)
 		die_out_of_memory();
 	return r;
@@ -701,7 +739,7 @@ expand_tcbtab(void)
 	   free the TCBs, we allocate a single chunk of many.  */
 	unsigned int i = tcbtabsize;
 	struct tcb *newtcbs = xcalloc(tcbtabsize, sizeof(newtcbs[0]));
-	struct tcb **newtab = xrealloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
+	struct tcb **newtab = xreallocarray(tcbtab, tcbtabsize * 2, sizeof(tcbtab[0]));
 	tcbtabsize *= 2;
 	tcbtab = newtab;
 	while (i < tcbtabsize)
diff --git a/syscall.c b/syscall.c
index d7c8ef4..c938cd7 100644
--- a/syscall.c
+++ b/syscall.c
@@ -381,7 +381,7 @@ reallocate_qual(const unsigned int n)
 	unsigned p;
 	qualbits_t *qp;
 	for (p = 0; p < SUPPORTED_PERSONALITIES; p++) {
-		qp = qual_vec[p] = xrealloc(qual_vec[p], n * sizeof(qualbits_t));
+		qp = qual_vec[p] = xreallocarray(qual_vec[p], n, sizeof(qualbits_t));
 		memset(&qp[num_quals], 0, (n - num_quals) * sizeof(qualbits_t));
 	}
 	num_quals = n;
diff --git a/unwind.c b/unwind.c
index 711bede..f31c619 100644
--- a/unwind.c
+++ b/unwind.c
@@ -193,8 +193,8 @@ build_mmap_cache(struct tcb* tcp)
 
 		if (tcp->mmap_cache_size >= cur_array_size) {
 			cur_array_size *= 2;
-			cache_head = xrealloc(cache_head,
-					     cur_array_size * sizeof(*cache_head));
+			cache_head = xreallocarray(cache_head,
+						   cur_array_size, sizeof(*cache_head));
 		}
 
 		entry = &cache_head[tcp->mmap_cache_size];
@@ -285,7 +285,7 @@ get_symbol_name(unw_cursor_t *cursor, char **name,
 			break;
 		}
 		*size *= 2;
-		*name = xrealloc(*name, *size);
+		*name = xreallocarray(*name, *size, 1);
 	}
 }
 
-- 
2.1.0





More information about the Strace-devel mailing list