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 <[email protected]>
---
 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 <[email protected]>
+ *
+ * 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


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to