chiark / gitweb /
integer and buffer overflows: introduce safe_malloc_ary
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 12 Jun 2011 21:28:33 +0000 (22:28 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 26 Jun 2011 11:07:25 +0000 (12:07 +0100)
When allocating an array, it is necessary to check that the
multiplication (to compute the size in bytes) does not overflow.

Do this in a new function safe_malloc_ary, which we call in both the
places where safe_malloc was previously used with an unchecked
multiplication.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
ipaddr.c
netlink.c
secnet.h
util.c

index 433db62ef406b7912a52a09f5d641080d9b3821d..8de384bfa190afadc7da9731a77c1ca9d794eac0 100644 (file)
--- a/ipaddr.c
+++ b/ipaddr.c
@@ -17,7 +17,7 @@ struct subnet_list *subnet_list_new(void)
     r=safe_malloc(sizeof(*r),"subnet_list_new:list");
     r->entries=0;
     r->alloc=DEFAULT_ALLOC;
-    r->list=safe_malloc(sizeof(*r->list)*r->alloc,"subnet_list_new:data");
+    r->list=safe_malloc_ary(sizeof(*r->list),r->alloc,"subnet_list_new:data");
     return r;
 }
 
index f6d4e72920ab7b9a28422ae200353e4a231dcb24..70eb9283b080104e37131d65170cdd7581988988 100644 (file)
--- a/netlink.c
+++ b/netlink.c
@@ -768,8 +768,8 @@ static void netlink_phase_hook(void *sst, uint32_t new_phase)
     /* All the networks serviced by the various tunnels should now
      * have been registered.  We build a routing table by sorting the
      * clients by priority.  */
-    st->routes=safe_malloc(st->n_clients*sizeof(*st->routes),
-                          "netlink_phase_hook");
+    st->routes=safe_malloc_ary(sizeof(*st->routes),st->n_clients,
+                              "netlink_phase_hook");
     /* Fill the table */
     i=0;
     for (c=st->clients; c; c=c->next) {
index 3f32302bc272a699dc742b91f2232f327c1b7853..18500c5cf3742421dddeb7d161082dfc4b4871c0 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -144,6 +144,7 @@ extern uint32_t string_list_to_word(list_t *l, struct flagstr *f,
 
 extern char *safe_strdup(const char *string, const char *message);
 extern void *safe_malloc(size_t size, const char *message);
+extern void *safe_malloc_ary(size_t size, size_t count, const char *message);
 
 extern int sys_cmd(const char *file, const char *argc, ...);
 
diff --git a/util.c b/util.c
index 86a9cd82d55eddf5134b0135f996ac90af922159..44a45e50d4c22d0c19350e9277e91d93d4ed65c3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -74,6 +74,12 @@ void *safe_malloc(size_t size, const char *message)
     }
     return r;
 }
+void *safe_malloc_ary(size_t size, size_t count, const char *message) {
+    if (count >= INT_MAX/size) {
+       fatal("array allocation overflow: %s", message);
+    }
+    return safe_malloc(size*count, message);
+}
 
 /* Convert a buffer into its MP_INT representation */
 void read_mpbin(MP_INT *a, uint8_t *bin, int binsize)