This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Use calloc (x, y) instead malloc (x * y).


Hi,

As there were several bugs with possible overflows in malloc calculation
we should try to prevent these. A simple heuristic is to use following
cocinelle patch:

@@ expression e1, e2; @@

- malloc(e1 * e2)
+ calloc(e1, e2)

To handle easy case. OK to commit?

./ChangeLog:


	* grp/initgroups.c: Use calloc instead malloc.
	* hesiod/hesiod.c: Likewise.
	* hurd/hurdmsg.c: Likewise.
	* hurd/hurdsig.c: Likewise.
	* iconv/gconv_cache.c: Likewise.
	* iconv/gconv_db.c: Likewise.
	* include/inline-hashtab.h: Likewise.
	* misc/getusershell.c: Likewise.
	* nis/nis_findserv.c: Likewise.
	* nis/nis_getservlist.c: Likewise.
	* nis/nis_subr.c: Likewise.
	* nis/nss_compat/compat-initgroups.c: Likewise.
	* nscd/initgrcache.c: Likewise.
	* nscd/nscd_getserv_r.c: Likewise.
	* posix/fnmatch.c: Likewise.
	* posix/regex_internal.h: Likewise.
	* stdio-common/_i18n_number.h: Likewise.
	* string/strxfrm_l.c: Likewise.
	* sunrpc/auth_unix.c: Likewise.
	* sunrpc/svc.c: Likewise.
	* sysdeps/gnu/ifaddrs.c: Likewise.
	* sysdeps/mach/hurd/i386/init-first.c: Likewise.
	* sysdeps/mach/hurd/if_index.c: Likewise.
	* sysdeps/unix/sysv/linux/if_index.c: Likewise.
	* timezone/zdump.c: Likewise.

./localedata/ChangeLog:


	* collate-test.c: Use calloc instead malloc.

./libidn/ChangeLog:


	* idna.c: Use calloc instead malloc.

---
 grp/initgroups.c                    | 4 ++--
 hesiod/hesiod.c                     | 2 +-
 hurd/hurdmsg.c                      | 2 +-
 hurd/hurdsig.c                      | 2 +-
 iconv/gconv_cache.c                 | 6 +++---
 iconv/gconv_db.c                    | 4 ++--
 include/inline-hashtab.h            | 2 +-
 libidn/idna.c                       | 4 ++--
 localedata/collate-test.c           | 3 +--
 misc/getusershell.c                 | 2 +-
 nis/nis_findserv.c                  | 2 +-
 nis/nis_getservlist.c               | 4 ++--
 nis/nis_subr.c                      | 3 +--
 nis/nss_compat/compat-initgroups.c  | 2 +-
 nscd/initgrcache.c                  | 3 +--
 nscd/nscd_getserv_r.c               | 6 +++---
 posix/fnmatch.c                     | 4 ++--
 posix/regex_internal.h              | 2 +-
 stdio-common/_i18n_number.h         | 2 +-
 string/strxfrm_l.c                  | 2 +-
 sunrpc/auth_unix.c                  | 2 +-
 sunrpc/svc.c                        | 2 +-
 sysdeps/gnu/ifaddrs.c               | 2 +-
 sysdeps/mach/hurd/i386/init-first.c | 2 +-
 sysdeps/mach/hurd/if_index.c        | 2 +-
 sysdeps/unix/sysv/linux/if_index.c  | 2 +-
 timezone/zdump.c                    | 2 +-
 29 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/grp/initgroups.c b/grp/initgroups.c
index 932d8fb..2c2a649 100644
--- a/grp/initgroups.c
+++ b/grp/initgroups.c
@@ -158,7 +158,7 @@ getgrouplist (const char *user, gid_t group, gid_t *groups, int *ngroups)
 {
   long int size = MAX (1, *ngroups);
 
-  gid_t *newgroups = (gid_t *) malloc (size * sizeof (gid_t));
+  gid_t *newgroups = (gid_t *) calloc (size, sizeof (gid_t));
   if (__builtin_expect (newgroups == NULL, 0))
     /* No more memory.  */
     // XXX This is wrong.  The user provided memory, we have to use
@@ -211,7 +211,7 @@ initgroups (const char *user, gid_t group)
     /* No fixed limit on groups.  Pick a starting buffer size.  */
     size = 16;
 
-  groups = (gid_t *) malloc (size * sizeof (gid_t));
+  groups = (gid_t *) calloc (size, sizeof (gid_t));
   if (__builtin_expect (groups == NULL, 0))
     /* No more memory.  */
     return -1;
diff --git a/hesiod/hesiod.c b/hesiod/hesiod.c
index 657dabe..fa7e67c 100644
--- a/hesiod/hesiod.c
+++ b/hesiod/hesiod.c
@@ -400,7 +400,7 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
 		cp += skip + QFIXEDSZ;
 	}
 
-	list = malloc((ancount + 1) * sizeof(char *));
+	list = calloc((ancount + 1), sizeof(char *));
 	if (!list)
 		return (NULL);
 	j = 0;
diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
index 6e350ee..197dd370 100644
--- a/hurd/hurdmsg.c
+++ b/hurd/hurdmsg.c
@@ -392,7 +392,7 @@ _S_msg_set_environment (mach_port_t msgport, mach_port_t auth,
   AUTHCHECK;
 
   envc = __argz_count (data, datalen);
-  envp = malloc ((envc + 1) * sizeof (char *));
+  envp = calloc ((envc + 1), sizeof (char *));
   if (envp == NULL)
     return errno;
   __argz_extract (data, datalen, envp);
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 558aa07..d3bb5b0 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -1269,7 +1269,7 @@ _hurdsig_init (const int *intarray, size_t intarraysize)
 
       __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
       __hurd_sigthread_variables =
-	malloc (__hurd_threadvar_max * sizeof (unsigned long int));
+	calloc (__hurd_threadvar_max, sizeof (unsigned long int));
       if (__hurd_sigthread_variables == NULL)
 	__libc_fatal ("hurd: Can't allocate threadvars for signal thread\n");
       memset (__hurd_sigthread_variables, 0,
diff --git a/iconv/gconv_cache.c b/iconv/gconv_cache.c
index ccd2d6e..7dfdc23 100644
--- a/iconv/gconv_cache.c
+++ b/iconv/gconv_cache.c
@@ -314,8 +314,8 @@ __gconv_lookup_cache (const char *toset, const char *fromset,
 
 	  *nsteps = extra->module_cnt;
 	  *handle = result =
-	    (struct __gconv_step *) malloc (extra->module_cnt
-					    * sizeof (struct __gconv_step));
+	    (struct __gconv_step *) calloc (extra->module_cnt,
+                                           sizeof (struct __gconv_step));
 	  if (result == NULL)
 	    return __GCONV_NOMEM;
 
@@ -369,7 +369,7 @@ __gconv_lookup_cache (const char *toset, const char *fromset,
     return __GCONV_NOCONV;
 
   /* We will use up to two modules.  Always allocate room for two.  */
-  result = (struct __gconv_step *) malloc (2 * sizeof (struct __gconv_step));
+  result = (struct __gconv_step *) calloc (2, sizeof (struct __gconv_step));
   if (result == NULL)
     return __GCONV_NOMEM;
 
diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
index b533dc0..9517da9 100644
--- a/iconv/gconv_db.c
+++ b/iconv/gconv_db.c
@@ -248,8 +248,8 @@ gen_steps (struct derivation_step *best, const char *toset,
   for (current = best; current->last != NULL; current = current->last)
     ++step_cnt;
 
-  result = (struct __gconv_step *) malloc (sizeof (struct __gconv_step)
-					   * step_cnt);
+  result = (struct __gconv_step *) calloc (sizeof (struct __gconv_step),
+					   step_cnt);
   if (result != NULL)
     {
       int failed = 0;
diff --git a/include/inline-hashtab.h b/include/inline-hashtab.h
index 863b377..17786aa 100644
--- a/include/inline-hashtab.h
+++ b/include/inline-hashtab.h
@@ -52,7 +52,7 @@ htab_create (void)
   if (! ht)
     return NULL;
   ht->size = 3;
-  ht->entries = malloc (sizeof (void *) * ht->size);
+  ht->entries = calloc (sizeof (void *), ht->size);
   ht->free = free;
   if (! ht->entries)
     {
diff --git a/libidn/idna.c b/libidn/idna.c
index 7a15a25..c3e60f8 100644
--- a/libidn/idna.c
+++ b/libidn/idna.c
@@ -88,7 +88,7 @@ idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags)
 	inasciirange = 0;
     if (inasciirange)
       {
-	src = malloc (sizeof (in[0]) * (inlen + 1));
+	src = calloc (sizeof (in[0]), (inlen + 1));
 	if (src == NULL)
 	  return IDNA_MALLOC_ERROR;
 
@@ -624,7 +624,7 @@ idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags)
 	;
 
       buflen = end - start;
-      buf = malloc (sizeof (buf[0]) * (buflen + 1));
+      buf = calloc (sizeof (buf[0]), (buflen + 1));
       if (!buf)
 	return IDNA_MALLOC_ERROR;
 
diff --git a/localedata/collate-test.c b/localedata/collate-test.c
index dfc15b0..df0a008 100644
--- a/localedata/collate-test.c
+++ b/localedata/collate-test.c
@@ -50,7 +50,7 @@ main (int argc, char *argv[])
 
   nstrings_max = 100;
   nstrings = 0;
-  strings = (struct lines *) malloc (nstrings_max * sizeof (struct lines));
+  strings = (struct lines *) calloc (nstrings_max, sizeof (struct lines));
   if (strings == NULL)
     {
       perror (argv[0]);
@@ -129,4 +129,3 @@ xstrcoll (ptr1, ptr2)
   const struct lines *l2 = (const struct lines *) ptr2;
 
   return strcoll (l1->key, l2->key);
-}
diff --git a/misc/getusershell.c b/misc/getusershell.c
index fc2c43b..2875e66 100644
--- a/misc/getusershell.c
+++ b/misc/getusershell.c
@@ -119,7 +119,7 @@ initshells (void)
 	flen = statb.st_size + 3;
 	if ((strings = malloc(flen)) == NULL)
 		goto init_okshells;
-	shells = malloc(statb.st_size / 3 * sizeof (char *));
+	shells = calloc(statb.st_size / 3, sizeof (char *));
 	if (shells == NULL) {
 		free(strings);
 		strings = NULL;
diff --git a/nis/nis_findserv.c b/nis/nis_findserv.c
index c5269c2..83e8b42 100644
--- a/nis/nis_findserv.c
+++ b/nis/nis_findserv.c
@@ -86,7 +86,7 @@ __nis_findfastest_with_timeout (dir_binding *bind,
   pings_max = bind->server_len * 2;	/* Reserve a little bit more memory
 					   for multihomed hosts */
   pings_count = 0;
-  pings = malloc (sizeof (struct findserv_req) * pings_max);
+  pings = calloc (sizeof (struct findserv_req), pings_max);
   xid_seed = (u_int32_t) (time (NULL) ^ getpid ());
 
   if (__builtin_expect (pings == NULL, 0))
diff --git a/nis/nis_getservlist.c b/nis/nis_getservlist.c
index 54840ab..cb4a23c 100644
--- a/nis/nis_getservlist.c
+++ b/nis/nis_getservlist.c
@@ -36,7 +36,7 @@ nis_getservlist (const_nis_name dir)
       nis_server *server;
 
       serv =
-	malloc (sizeof (nis_server *) *
+	calloc (sizeof (nis_server *),
 		(NIS_RES_OBJECT (res)->DI_data.do_servers.do_servers_len + 1));
       if (__builtin_expect (serv == NULL, 0))
 	{
@@ -94,7 +94,7 @@ nis_getservlist (const_nis_name dir)
               unsigned long int j;
 
               serv[i]->ep.ep_val =
-		malloc (server->ep.ep_len * sizeof (endpoint));
+		calloc (server->ep.ep_len, sizeof (endpoint));
 	      if (__builtin_expect (serv[i]->ep.ep_val == NULL, 0))
 		{
 		  ++i;
diff --git a/nis/nis_subr.c b/nis/nis_subr.c
index a03600d..5211b4e 100644
--- a/nis/nis_subr.c
+++ b/nis/nis_subr.c
@@ -117,7 +117,7 @@ nis_getnames (const_nis_name name)
   const char *cp2;
 
   int count = 2;
-  nis_name *getnames = malloc ((count + 1) * sizeof (char *));
+  nis_name *getnames = calloc ((count + 1), sizeof (char *));
   if (__builtin_expect (getnames == NULL, 0))
       return NULL;
 
@@ -348,4 +348,3 @@ nis_destroy_object (nis_object *obj)
 {
   nis_free_object (obj);
 }
-libnsl_hidden_def (nis_destroy_object)
diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c
index cf924c4..e8135e3 100644
--- a/nis/nss_compat/compat-initgroups.c
+++ b/nis/nss_compat/compat-initgroups.c
@@ -281,7 +281,7 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
     {
       long int mystart = 0;
       long int mysize = limit <= 0 ? *size : limit;
-      gid_t *mygroups = malloc (mysize * sizeof (gid_t));
+      gid_t *mygroups = calloc (mysize, sizeof (gid_t));
 
       if (mygroups == NULL)
 	return NSS_STATUS_TRYAGAIN;
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index 4580884..b1e0405 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -111,7 +111,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
   /* This is temporary memory, we need not (and must not) call
      mempool_alloc.  */
   // XXX This really should use alloca.  need to change the backends.
-  gid_t *groups = (gid_t *) malloc (size * sizeof (gid_t));
+  gid_t *groups = (gid_t *) calloc (size, sizeof (gid_t));
   if (__builtin_expect (groups == NULL, 0))
     /* No more memory.  */
     goto out;
@@ -442,4 +442,3 @@ readdinitgroups (struct database_dyn *db, struct hashentry *he,
     };
 
   return addinitgroupsX (db, -1, &req, db->data + he->key, he->owner, he, dh);
-}
diff --git a/nscd/nscd_getserv_r.c b/nscd/nscd_getserv_r.c
index c9c890c..f1bfff7 100644
--- a/nscd/nscd_getserv_r.c
+++ b/nscd/nscd_getserv_r.c
@@ -160,7 +160,7 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
 				      alloca_used);
 	      else
 		{
-		  tmp = malloc (serv_resp.s_aliases_cnt * sizeof (uint32_t));
+		  tmp = calloc (serv_resp.s_aliases_cnt, sizeof (uint32_t));
 		  if (tmp == NULL)
 		    {
 		      retval = ENOMEM;
@@ -257,8 +257,8 @@ nscd_getserv_r (const char *crit, size_t critlen, const char *proto,
 					      alloca_used);
 	      else
 		{
-		  aliases_len = malloc (serv_resp.s_aliases_cnt
-					* sizeof (uint32_t));
+		  aliases_len = calloc (serv_resp.s_aliases_cnt,
+					sizeof (uint32_t));
 		  if (aliases_len == NULL)
 		    {
 		      retval = ENOMEM;
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index 0f26a2e..39ca125 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -379,7 +379,7 @@ fnmatch (pattern, string, flags)
 	      return -2;
 	    }
 	  wpattern_malloc = wpattern
-	    = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
+	    = (wchar_t *) calloc ((n + 1), sizeof (wchar_t));
 	  assert (mbsinit (&ps));
 	  if (wpattern == NULL)
 	    return -2;
@@ -430,7 +430,7 @@ fnmatch (pattern, string, flags)
 	    }
 
 	  wstring_malloc = wstring
-	    = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
+	    = (wchar_t *) calloc ((n + 1), sizeof (wchar_t));
 	  if (wstring == NULL)
 	    {
 	      free (wpattern_malloc);
diff --git a/posix/regex_internal.h b/posix/regex_internal.h
index 3c94fbe..941613c 100644
--- a/posix/regex_internal.h
+++ b/posix/regex_internal.h
@@ -429,7 +429,7 @@ static unsigned int re_string_context_at (const re_string_t *input, int idx,
 # endif
 #endif
 
-#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
+#define re_malloc(t,n) ((t *) calloc ((n), sizeof (t)))
 #define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
 #define re_free(p) free (p)
 
diff --git a/stdio-common/_i18n_number.h b/stdio-common/_i18n_number.h
index edb7fc3..4ee58b2 100644
--- a/stdio-common/_i18n_number.h
+++ b/stdio-common/_i18n_number.h
@@ -70,7 +70,7 @@ _i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr, CHAR_T *end)
     src = (CHAR_T *) alloca ((rear_ptr - w) * sizeof (CHAR_T));
   else
     {
-      src = (CHAR_T *) malloc ((rear_ptr - w) * sizeof (CHAR_T));
+      src = (CHAR_T *) calloc ((rear_ptr - w), sizeof (CHAR_T));
       if (src == NULL)
 	/* If we cannot allocate the memory don't rewrite the string.
 	   It is better than nothing.  */
diff --git a/string/strxfrm_l.c b/string/strxfrm_l.c
index 3812ed6..a8ba2d5 100644
--- a/string/strxfrm_l.c
+++ b/string/strxfrm_l.c
@@ -151,7 +151,7 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
      very conservative here.  */
   if (! __libc_use_alloca ((srclen + 1) * (sizeof (int32_t) + 1)))
     {
-      idxarr = (int32_t *) malloc ((srclen + 1) * (sizeof (int32_t) + 1));
+      idxarr = (int32_t *) calloc ((srclen + 1), (sizeof (int32_t) + 1));
       rulearr = (unsigned char *) &idxarr[srclen];
 
       if (idxarr == NULL)
diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
index 68b42d7..863b177 100644
--- a/sunrpc/auth_unix.c
+++ b/sunrpc/auth_unix.c
@@ -183,7 +183,7 @@ authunix_create_default (void)
     gids = (gid_t *) alloca (max_nr_groups * sizeof (gid_t));
   else
     {
-      gids = (gid_t *) malloc (max_nr_groups * sizeof (gid_t));
+      gids = (gid_t *) calloc (max_nr_groups, sizeof (gid_t));
       if (gids == NULL)
 	return NULL;
     }
diff --git a/sunrpc/svc.c b/sunrpc/svc.c
index 53e5d9f..cfc7b5b 100644
--- a/sunrpc/svc.c
+++ b/sunrpc/svc.c
@@ -97,7 +97,7 @@ xprt_register (SVCXPRT *xprt)
 
   if (xports == NULL)
     {
-      xports = (SVCXPRT **) malloc (_rpc_dtablesize () * sizeof (SVCXPRT *));
+      xports = (SVCXPRT **) calloc (_rpc_dtablesize (), sizeof (SVCXPRT *));
       if (xports == NULL) /* Don´t add handle */
 	return;
     }
diff --git a/sysdeps/gnu/ifaddrs.c b/sysdeps/gnu/ifaddrs.c
index 3626c30..158d4b5 100644
--- a/sysdeps/gnu/ifaddrs.c
+++ b/sysdeps/gnu/ifaddrs.c
@@ -66,7 +66,7 @@ getifaddrs (struct ifaddrs **ifap)
       struct ifreq *ifr;
       int i;
 
-      storage = malloc (nifs * sizeof storage[0]);
+      storage = calloc (nifs, sizeof storage[0]);
       if (storage == NULL)
 	{
 	  __close (fd);
diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c
index 8fb613b..976a094 100644
--- a/sysdeps/mach/hurd/i386/init-first.c
+++ b/sysdeps/mach/hurd/i386/init-first.c
@@ -268,7 +268,7 @@ init (int *data)
 
       void call_init1 (void);
 
-      array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
+      array = calloc (__hurd_threadvar_max, sizeof (unsigned long int));
       if (array == NULL)
 	__libc_fatal ("Can't allocate single-threaded thread variables.");
 
diff --git a/sysdeps/mach/hurd/if_index.c b/sysdeps/mach/hurd/if_index.c
index 713f731..315e582 100644
--- a/sysdeps/mach/hurd/if_index.c
+++ b/sysdeps/mach/hurd/if_index.c
@@ -106,7 +106,7 @@ if_nameindex (void)
       nifs = len / sizeof (struct ifreq);
     }
 
-  idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
+  idx = calloc ((nifs + 1), sizeof (struct if_nameindex));
   if (idx == NULL)
     {
       err = ENOBUFS;
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index c08bc34..f3dfe16 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -115,7 +115,7 @@ if_nameindex_netlink (void)
 	}
     }
 
-  idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
+  idx = calloc ((nifs + 1), sizeof (struct if_nameindex));
   if (idx == NULL)
     {
     nomem:
diff --git a/timezone/zdump.c b/timezone/zdump.c
index 9255aff..db9e3ad 100644
--- a/timezone/zdump.c
+++ b/timezone/zdump.c
@@ -357,7 +357,7 @@ main(int argc, char *argv[])
 
 		for (i = 0; environ[i] != NULL; ++i)
 			continue;
-		fakeenv = malloc((i + 2) * sizeof *fakeenv);
+		fakeenv = calloc((i + 2), sizeof *fakeenv);
 		if (fakeenv == NULL
 		    || (fakeenv[0] = malloc(longest + 4)) == NULL) {
 					(void) perror(progname);
-- 
1.8.4.rc3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]