bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* [PATCH 1/2] Add nmalloc, NMALLOC et al.
@ 2013-11-03 12:13 Ondřej Bílka
  2013-11-03 12:28 ` [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows Ondřej Bílka
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Ondřej Bílka @ 2013-11-03 12:13 UTC (permalink / raw
  To: bug-gnulib

Hi,

For syncing with libc refactoring of malloc following patch adds for
consistency nmalloc variants.

These will make overflow checking of common allocations automatic as in
next patch.

	* lib/xalloc.h (NMALLOC, NREALLOC, nmalloc, nrealloc): Add.
	* lib/xmalloca.h (XNMALLOCA): Likewise.

diff --git a/lib/xalloc.h b/lib/xalloc.h
index 6c9b53b..e336f1c 100644
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
@@ -93,6 +93,15 @@ char *xstrdup (char const *str)
 #define XCALLOC(n, t) \
    ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
 
+/* Allocate memory for N elements of type T, with overflow checking.  */
+/* extern t *NMALLOC (size_t n, typename t); */
+#define NMALLOC(n, t) \
+   ((t *) (sizeof (t) == 1 ? malloc (n) : nmalloc (n, sizeof (t))))
+
+/* Rellocate memory for N elements of type T, with overflow checking. */
+/* extern t *NREALLOC (void *p, size_t n, typename t); */
+#define NREALLOC(p, n, t) ((t *) (nrealloc (p, n, sizeof (t))))
+
 
 /* Allocate an array of N objects, each with S bytes of memory,
    dynamically, with error checking.  S must be nonzero.  */
@@ -107,6 +116,19 @@ xnmalloc (size_t n, size_t s)
   return xmalloc (n * s);
 }
 
+/* Allocate an array of N objects, each with S bytes of memory,
+   dynamically, with overflow checking.  S must be nonzero.  */
+
+XALLOC_INLINE void *nmalloc (size_t n, size_t s)
+                    _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
+XALLOC_INLINE void *
+nmalloc (size_t n, size_t s)
+{
+  if (xalloc_oversized (n, s))
+    xalloc_die ();
+  return xmalloc (n * s);
+}
+
 /* Change the size of an allocated block of memory P to an array of N
    objects each of S bytes, with error checking.  S must be nonzero.  */
 
@@ -120,6 +142,19 @@ xnrealloc (void *p, size_t n, size_t s)
   return xrealloc (p, n * s);
 }
 
+/* Change the size of an allocated block of memory P to an array of N
+   objects each of S bytes, with overflow checking.  */
+
+XALLOC_INLINE void *nrealloc (void *p, size_t n, size_t s)
+                    _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
+XALLOC_INLINE void *
+nrealloc (void *p, size_t n, size_t s)
+{
+  if (s == 0 || xalloc_oversized (n, s))
+    return NULL;
+  return xrealloc (p, n * s);
+}
+
 /* If P is null, allocate a block of at least *PN such objects;
    otherwise, reallocate P so that it contains more than *PN objects
    each of S bytes.  *PN must be nonzero unless P is null, and S must
diff --git a/lib/xmalloca.h b/lib/xmalloca.h
index 2f7567d..4ab1a03 100644
--- a/lib/xmalloca.h
+++ b/lib/xmalloca.h
@@ -55,6 +55,7 @@ extern void * xmmalloca (size_t n);
     xnmalloc ((n), (s))
 #endif
 
+#define XNMALLOCA(n, t) ((t *) xnmalloca (x, sizeof (t)))
 
 #ifdef __cplusplus
 }


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows.
  2013-11-03 12:13 [PATCH 1/2] Add nmalloc, NMALLOC et al Ondřej Bílka
@ 2013-11-03 12:28 ` Ondřej Bílka
  2013-11-03 20:09   ` Paul Eggert
  2013-11-03 20:04 ` [PATCH 1/2] Add nmalloc, NMALLOC et al Paul Eggert
  2013-11-06 12:27 ` Richard W.M. Jones
  2 siblings, 1 reply; 12+ messages in thread
From: Ondřej Bílka @ 2013-11-03 12:28 UTC (permalink / raw
  To: bug-gnulib

[-- Attachment #1: Type: text/plain, Size: 597 bytes --]


A malloc that contains multiplication that migth overflow could be
converted to one that does not almost automatically (unless user is so
clever that he can utilize overflow.)

This is not patch but a patch generator, it could be used to produce
patch for each project that uses malloc.

For conversion you need to have http://coccinelle.lip6.fr/ installed.

Then run attached nmalloc wrapper script to generate patch.

Then if you want to generate changelogs with list of all functions touched 
you I attached files for changelog generation that are used by running
 mkchlog and using Log file.

[-- Attachment #2: nmalloc --]
[-- Type: text/plain, Size: 1906 bytes --]


echo "@@ expression e1; type t; @@

- (t *) xmalloca (e1 * sizeof (t))
+ XNMALLOCA (e1, t)" > /tmp/xmalloca1.cocci

echo "@@ expression e1; type t; @@

- xmalloca (e1 * sizeof (t))
+ XNMALLOCA (e1, t)" > /tmp/xmalloca2.cocci

echo "@@ expression e1, e2; @@

- xmalloca (e1 * e2)
+ xnmalloca (e1, e2)" > /tmp/xmalloca3.cocci

SPATCHES='/tmp/xmalloca1.cocci /tmp/xmalloca2.cocci /tmp/xmalloca3.cocci'

for FILE in `git grep --name-only 'malloca (' | grep 'c$' | grep -v test | grep -v bug`; do
  echo $FILE
  for SPATCH in $SPATCHES; do
    timeout 10s spatch $SPATCH -in_place $FILE 2> /dev/null
  done
done


echo "@@ expression e1; type t; @@

- (t *) malloc (e1 * sizeof (t))
+ NMALLOC (e1, t)" > /tmp/malloc1.cocci

echo "@@ expression e1; type t; @@

- malloc (e1 * sizeof (t))
+ NMALLOC (e1, t)" > /tmp/malloc2.cocci

echo "@@ expression e1, e2; @@

- malloc (e1 * e2)
+ nmalloc (e1, e2)" > /tmp/malloc3.cocci

SPATCHES='/tmp/malloc1.cocci /tmp/malloc2.cocci /tmp/malloc3.cocci'

for FILE in `git grep --name-only 'malloc (' | grep 'c$' | grep -v test | grep -v bug`; do
  echo $FILE
  for SPATCH in $SPATCHES; do
    timeout 10s spatch $SPATCH -in_place $FILE 2> /dev/null
  done
done



echo "@@ expression e, e1; type t; @@

- (t *) realloc (e, e1 * sizeof (t))
+ NREALLOC (e, e1, t)" > /tmp/realloc1.cocci

echo "@@ expression e, e1; type t; @@

- realloc (e, e1 * sizeof (t))
+ NREALLOC (e, e1, t)" > /tmp/realloc2.cocci

echo "@@ expression e, e1, e2; @@

- realloc (e, e1 * e2)
+ nrealloc (e, e1, e2)" > /tmp/malloc3.cocci

SPATCHES='/tmp/realloc1.cocci /tmp/realloc2.cocci /tmp/realloc3.cocci'

for FILE in `git grep --name-only 'realloc (' | grep 'c$' | grep -v test | grep -v bug`; do
  echo $FILE
  for SPATCH in $SPATCHES; do
    timeout 10s spatch $SPATCH -in_place $FILE 2> /dev/null
  done
done

git diff | sed -e "s/^+\(.*[a-zA-Z0-9_]\)(/+\1 (/" > diff
git checkout -f
git apply diff

[-- Attachment #3: mkchlog --]
[-- Type: text/plain, Size: 279 bytes --]

#!/bin/bash
rm Log 2> /dev/null
TMP=`mktemp`
echo  "`date +%Y-%m-%d`  `git log --pretty="%an  <%ae>" | head -n 1`" > Log
echo >> Log

for FILE in `git diff --name-only`; do
  git diff $FILE > $TMP
  FNS=`perl diff.pl $TMP $FILE`
  echo  "\t* $FILE ($FNS): Likewise." >> Log
done

[-- Attachment #4: diff.pl --]
[-- Type: application/x-perl, Size: 191 bytes --]

[-- Attachment #5: fname.pl --]
[-- Type: application/x-perl, Size: 179 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-03 12:13 [PATCH 1/2] Add nmalloc, NMALLOC et al Ondřej Bílka
  2013-11-03 12:28 ` [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows Ondřej Bílka
@ 2013-11-03 20:04 ` Paul Eggert
  2013-11-03 20:13   ` Ondřej Bílka
  2013-11-06 12:27 ` Richard W.M. Jones
  2 siblings, 1 reply; 12+ messages in thread
From: Paul Eggert @ 2013-11-03 20:04 UTC (permalink / raw
  To: Ondřej Bílka, bug-gnulib

Ondřej Bílka wrote:
> +XALLOC_INLINE void *
> +nmalloc (size_t n, size_t s)
> +{
> +  if (xalloc_oversized (n, s))
> +    xalloc_die ();
> +  return xmalloc (n * s);
> +}

This is the same as the existing xnmalloc, so why bother with a new name?
Similarly for the other changes.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows.
  2013-11-03 12:28 ` [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows Ondřej Bílka
@ 2013-11-03 20:09   ` Paul Eggert
  2013-11-03 21:25     ` Ondřej Bílka
  0 siblings, 1 reply; 12+ messages in thread
From: Paul Eggert @ 2013-11-03 20:09 UTC (permalink / raw
  To: Ondřej Bílka, bug-gnulib

For something like this, it'd be better to tell us which
gnulib changes should be made, rather than merely supplying
a coccinelle recipe.  The xalloc.h changes should come first,
tho.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-03 20:04 ` [PATCH 1/2] Add nmalloc, NMALLOC et al Paul Eggert
@ 2013-11-03 20:13   ` Ondřej Bílka
  2013-11-03 20:17     ` Paul Eggert
  2013-11-03 20:36     ` Ondřej Bílka
  0 siblings, 2 replies; 12+ messages in thread
From: Ondřej Bílka @ 2013-11-03 20:13 UTC (permalink / raw
  To: Paul Eggert; +Cc: bug-gnulib

On Sun, Nov 03, 2013 at 12:04:36PM -0800, Paul Eggert wrote:
> Ondřej Bílka wrote:
> > +XALLOC_INLINE void *
> > +nmalloc (size_t n, size_t s)
> > +{
> > +  if (xalloc_oversized (n, s))
> > +    xalloc_die ();
> > +  return xmalloc (n * s);
> > +}
> 
> This is the same as the existing xnmalloc, so why bother with a new name?
> Similarly for the other changes.

I accidentally inlined wrong version. As idea is to handle overflow by
oom logic these should be:

nmalloc (size_t n, size_t s)
{
  if (xalloc_oversized (n, s))
    NULL;
  return malloc (n * s);
}



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-03 20:13   ` Ondřej Bílka
@ 2013-11-03 20:17     ` Paul Eggert
  2013-11-03 20:36     ` Ondřej Bílka
  1 sibling, 0 replies; 12+ messages in thread
From: Paul Eggert @ 2013-11-03 20:17 UTC (permalink / raw
  To: Ondřej Bílka; +Cc: bug-gnulib

Ondřej Bílka wrote:
> nmalloc (size_t n, size_t s)
> {
>   if (xalloc_oversized (n, s))
>     NULL;
>   return malloc (n * s);
> }

OK, I see.  This also needs to set errno, NO?



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-03 20:13   ` Ondřej Bílka
  2013-11-03 20:17     ` Paul Eggert
@ 2013-11-03 20:36     ` Ondřej Bílka
  1 sibling, 0 replies; 12+ messages in thread
From: Ondřej Bílka @ 2013-11-03 20:36 UTC (permalink / raw
  To: Paul Eggert; +Cc: bug-gnulib

On Sun, Nov 03, 2013 at 09:13:33PM +0100, Ondřej Bílka wrote:
> On Sun, Nov 03, 2013 at 12:04:36PM -0800, Paul Eggert wrote:
> > Ondřej Bílka wrote:
> > > +XALLOC_INLINE void *
> > > +nmalloc (size_t n, size_t s)
> > > +{
> > > +  if (xalloc_oversized (n, s))
> > > +    xalloc_die ();
> > > +  return xmalloc (n * s);
> > > +}
> > 
> > This is the same as the existing xnmalloc, so why bother with a new name?
> > Similarly for the other changes.
> 
> I accidentally inlined wrong version. As idea is to handle overflow by
> oom logic these should be:
> 
> nmalloc (size_t n, size_t s)
> {
>   if (xalloc_oversized (n, s))
>     NULL;
>   return malloc (n * s);
> }
> 

A new version is here. Macros are added for consistency of api but not
neccessary.

	* lib/xalloc.h (NMALLOC, NREALLOC, nmalloc, nrealloc): Add.
	* lib/xmalloca.h (XNMALLOCA): Likewise.

diff --git a/lib/xalloc.h b/lib/xalloc.h
index 6c9b53b..66799be 100644
--- a/lib/xalloc.h
+++ b/lib/xalloc.h
@@ -93,6 +93,15 @@ char *xstrdup (char const *str)
 #define XCALLOC(n, t) \
    ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
 
+/* Allocate memory for N elements of type T, with overflow checking.  */
+/* extern t *NMALLOC (size_t n, typename t); */
+#define NMALLOC(n, t) \
+   ((t *) (sizeof (t) == 1 ? malloc (n) : nmalloc (n, sizeof (t))))
+
+/* Rellocate memory for N elements of type T, with overflow checking. */
+/* extern t *NREALLOC (void *p, size_t n, typename t); */
+#define NREALLOC(p, n, t) ((t *) (nrealloc (p, n, sizeof (t))))
+
 
 /* Allocate an array of N objects, each with S bytes of memory,
    dynamically, with error checking.  S must be nonzero.  */
@@ -107,6 +116,17 @@ xnmalloc (size_t n, size_t s)
   return xmalloc (n * s);
 }
 
+/* Allocate an array of N objects, each with S bytes of memory,
+   dynamically, with overflow checking.  S must be nonzero.  */
+
+XALLOC_INLINE void *nmalloc (size_t n, size_t s)
+                    _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
+XALLOC_INLINE void *
+nmalloc (size_t n, size_t s)
+{
+  return malloc (xalloc_oversized (n, s) ? SIZE_MAX : n * s);
+}
+
 /* Change the size of an allocated block of memory P to an array of N
    objects each of S bytes, with error checking.  S must be nonzero.  */
 
@@ -120,6 +140,17 @@ xnrealloc (void *p, size_t n, size_t s)
   return xrealloc (p, n * s);
 }
 
+/* Change the size of an allocated block of memory P to an array of N
+   objects each of S bytes, with overflow checking.  S must be nonzero.  */
+
+XALLOC_INLINE void *nrealloc (void *p, size_t n, size_t s)
+                    _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
+XALLOC_INLINE void *
+nrealloc (void *p, size_t n, size_t s)
+{
+  return realloc (p, xalloc_oversized (n, s) ? SIZE_MAX : n * s);
+}
+
 /* If P is null, allocate a block of at least *PN such objects;
    otherwise, reallocate P so that it contains more than *PN objects
    each of S bytes.  *PN must be nonzero unless P is null, and S must
diff --git a/lib/xmalloca.h b/lib/xmalloca.h
index 2f7567d..4ab1a03 100644
--- a/lib/xmalloca.h
+++ b/lib/xmalloca.h
@@ -55,6 +55,7 @@ extern void * xmmalloca (size_t n);
     xnmalloc ((n), (s))
 #endif
 
+#define XNMALLOCA(n, t) ((t *) xnmalloca (x, sizeof (t)))
 
 #ifdef __cplusplus
 }


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows.
  2013-11-03 20:09   ` Paul Eggert
@ 2013-11-03 21:25     ` Ondřej Bílka
  0 siblings, 0 replies; 12+ messages in thread
From: Ondřej Bílka @ 2013-11-03 21:25 UTC (permalink / raw
  To: Paul Eggert; +Cc: bug-gnulib

On Sun, Nov 03, 2013 at 12:09:27PM -0800, Paul Eggert wrote:
> For something like this, it'd be better to tell us which
> gnulib changes should be made, rather than merely supplying
> a coccinelle recipe.  The xalloc.h changes should come first,
> tho.

Here are changes that I obtained by enabling only nmalloc and nrealloc
overwriting.

In several cases I remove a check that nmalloc made duplicate.

For regular expressions a  special handling is needed which will come as
separate patch.

2013-11-03  Ondřej Bílka  <neleai@seznam.cz>

	* lib/argp-help.c (make_hol, hol_append): Use nmalloc and nrealloc.
	* lib/error.c (error_tail): Likewise.
	* lib/fchdir.c (ensure_dirs_slot): Likewise.
	* lib/file-has-acl.c (file_has_acl): Likewise.
	* lib/fnmatch.c (fnmatch): Likewise.
	* lib/fts.c (fts_sort): Likewise.
	* lib/getgroups.c (rpl_getgroups): Likewise.
	* lib/gl_array_list.c (gl_array_nx_create): Likewise.
	* lib/gl_carray_list.c (gl_carray_nx_create): Likewise.
	* lib/glob.c (glob, glob_in_dir): Likewise.
	* lib/glthread/lock.c (gl_waitqueue_add): Likewise.
	* lib/group-member.c (get_group_info): Likewise.
	* lib/mgetgroups.c (realloc_groupbuf): Likewise.
	* lib/putenv.c (putenv): Likewise.
	* lib/qcopy-acl.c (qcopy_acl): Likewise.
	* lib/qset-acl.c (qset_acl): Likewise.
	* lib/regexec.c (build_trtable): Likewise.
	* lib/safe-alloc.c (safe_alloc_alloc_n, safe_alloc_realloc_n): Likewise.
	* lib/scandir.c (SCANDIR): Likewise.
	* lib/setenv.c (__add_to_environ): Likewise.
	* lib/spawn_faction_init.c: Likewise.
	* lib/uniconv/u16-conv-to-enc.c (FUNC): Likewise.
	* lib/unigbrk/ulc-grapheme-breaks.c (ulc_grapheme_breaks): Likewise.
	* lib/unilbrk/ulc-possible-linebreaks.c
	(ulc_possible_linebreaks): Likewise.
	* lib/unilbrk/ulc-width-linebreaks.c (ulc_width_linebreaks): Likewise.
	* lib/uninorm/uninorm-filter.c (uninorm_filter_write): Likewise.
	* lib/unistr/u16-to-u32.c (FUNC): Likewise.
	* lib/unistr/u16-to-u8.c (FUNC): Likewise.
	* lib/unistr/u32-to-u16.c (FUNC): Likewise.
	* lib/unistr/u32-to-u8.c (FUNC): Likewise.
	* lib/unistr/u8-to-u16.c (FUNC): Likewise.
	* lib/unistr/u8-to-u32.c (FUNC): Likewise.
	* lib/uniwbrk/ulc-wordbreaks.c (ulc_wordbreaks): Likewise.
	* lib/vasnprintf.c (multiply, divide, decode_long_double,
	decode_double, scale10_round_decimal_decoded): Likewise.
	* lib/wait-process.c (register_slave_subprocess): Likewise.

diff --git a/lib/argp-help.c b/lib/argp-help.c
index 85def44..fa04b02 100644
--- a/lib/argp-help.c
+++ b/lib/argp-help.c
@@ -460,7 +460,7 @@ make_hol (const struct argp *argp, struct hol_cluster *cluster)
             num_short_options++;        /* This is an upper bound.  */
         }
 
-      hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
+      hol->entries = nmalloc (sizeof (struct hol_entry), hol->num_entries);
       hol->short_options = malloc (num_short_options + 1);
 
       assert (hol->entries && hol->short_options);
@@ -874,7 +874,7 @@ hol_append (struct hol *hol, struct hol *more)
           struct hol_entry *e;
           unsigned num_entries = hol->num_entries + more->num_entries;
           struct hol_entry *entries =
-            malloc (num_entries * sizeof (struct hol_entry));
+            nmalloc (num_entries, sizeof (struct hol_entry));
           unsigned hol_so_len = strlen (hol->short_options);
           char *short_options =
             malloc (hol_so_len + strlen (more->short_options) + 1);
diff --git a/lib/error.c b/lib/error.c
index 865b293..9d6aee6 100644
--- a/lib/error.c
+++ b/lib/error.c
@@ -218,8 +218,8 @@ error_tail (int status, int errnum, const char *message, va_list args)
               if (!use_malloc)
                 wmessage = NULL;
 
-              wchar_t *p = (wchar_t *) realloc (wmessage,
-                                                len * sizeof (wchar_t));
+              wchar_t *p = (wchar_t *) nrealloc (wmessage, len,
+						 sizeof (wchar_t));
               if (p == NULL)
                 {
                   free (wmessage);
diff --git a/lib/fchdir.c b/lib/fchdir.c
index 36a8e35..2aba01c 100644
--- a/lib/fchdir.c
+++ b/lib/fchdir.c
@@ -72,8 +72,8 @@ ensure_dirs_slot (size_t fd)
         new_allocated = fd + 1;
       new_dirs =
         (dirs != NULL
-         ? (dir_info_t *) realloc (dirs, new_allocated * sizeof *dirs)
-         : (dir_info_t *) malloc (new_allocated * sizeof *dirs));
+         ? (dir_info_t *) nrealloc (dirs, new_allocated, sizeof *dirs)
+         : (dir_info_t *) nmalloc (new_allocated, sizeof *dirs));
       if (new_dirs == NULL)
         return false;
       memset (new_dirs + dirs_allocated, 0,
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index bb8bae1..cf4dc17 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -598,7 +598,7 @@ file_has_acl (char const *name, struct stat const *sb)
                   }
                 alloc = 2 * alloc; /* <= alloc_max */
                 entries = malloced =
-                  (aclent_t *) malloc (alloc * sizeof (aclent_t));
+                  (aclent_t *) nmalloc (alloc, sizeof (aclent_t));
                 if (entries == NULL)
                   {
                     errno = ENOMEM;
@@ -673,7 +673,7 @@ file_has_acl (char const *name, struct stat const *sb)
                     return -1;
                   }
                 alloc = 2 * alloc; /* <= alloc_max */
-                entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
+                entries = malloced = (ace_t *) nmalloc (alloc, sizeof (ace_t));
                 if (entries == NULL)
                   {
                     errno = ENOMEM;
diff --git a/lib/fnmatch.c b/lib/fnmatch.c
index 794d974..1a0ff02 100644
--- a/lib/fnmatch.c
+++ b/lib/fnmatch.c
@@ -307,7 +307,7 @@ fnmatch (const char *pattern, const char *string, int flags)
                 wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t));
               else
                 {
-                  wpattern = malloc (totsize * sizeof (wchar_t));
+                  wpattern = nmalloc (totsize, sizeof (wchar_t));
                   if (__builtin_expect (! wpattern, 0))
                     {
                       errno = ENOMEM;
diff --git a/lib/fts.c b/lib/fts.c
index 74968b3..3dab42d 100644
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -1870,9 +1870,8 @@ fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
                 FTSENT **a;
 
                 sp->fts_nitems = nitems + 40;
-                if (SIZE_MAX / sizeof *a < sp->fts_nitems
-                    || ! (a = realloc (sp->fts_array,
-                                       sp->fts_nitems * sizeof *a))) {
+                if (!(a = nrealloc (sp->fts_array, sp->fts_nitems,
+				    sizeof *a))) {
                         free(sp->fts_array);
                         sp->fts_array = NULL;
                         sp->fts_nitems = 0;
diff --git a/lib/getgroups.c b/lib/getgroups.c
index 9856adc..4ab3a21 100644
--- a/lib/getgroups.c
+++ b/lib/getgroups.c
@@ -69,12 +69,7 @@ rpl_getgroups (int n, gid_t *group)
       if (sizeof *group == sizeof *gbuf)
         return getgroups (n, (GETGROUPS_T *) group);
 
-      if (SIZE_MAX / sizeof *gbuf <= n)
-        {
-          errno = ENOMEM;
-          return -1;
-        }
-      gbuf = malloc (n * sizeof *gbuf);
+      gbuf = nmalloc (n, sizeof *gbuf);
       if (!gbuf)
         return -1;
       result = getgroups (n, gbuf);
@@ -96,7 +91,7 @@ rpl_getgroups (int n, gid_t *group)
       /* No need to worry about address arithmetic overflow here,
          since the ancient systems that we're running on have low
          limits on the number of secondary groups.  */
-      gbuf = malloc (n * sizeof *gbuf);
+      gbuf = nmalloc (n, sizeof *gbuf);
       if (!gbuf)
         return -1;
       n_groups = getgroups (n, gbuf);
diff --git a/lib/gl_array_list.c b/lib/gl_array_list.c
index af5f891..28e4174 100644
--- a/lib/gl_array_list.c
+++ b/lib/gl_array_list.c
@@ -95,9 +95,7 @@ gl_array_nx_create (gl_list_implementation_t implementation,
   list->base.allow_duplicates = allow_duplicates;
   if (count > 0)
     {
-      if (size_overflow_p (xtimes (count, sizeof (const void *))))
-        goto fail;
-      list->elements = (const void **) malloc (count * sizeof (const void *));
+      list->elements = (const void **) nmalloc (count, sizeof (const void *));
       if (list->elements == NULL)
         goto fail;
       memcpy (list->elements, contents, count * sizeof (const void *));
diff --git a/lib/gl_carray_list.c b/lib/gl_carray_list.c
index 5661b31..21a9f9b 100644
--- a/lib/gl_carray_list.c
+++ b/lib/gl_carray_list.c
@@ -99,9 +99,7 @@ gl_carray_nx_create (gl_list_implementation_t implementation,
   list->base.allow_duplicates = allow_duplicates;
   if (count > 0)
     {
-      if (size_overflow_p (xtimes (count, sizeof (const void *))))
-        goto fail;
-      list->elements = (const void **) malloc (count * sizeof (const void *));
+      list->elements = (const void **) nmalloc (count, sizeof (const void *));
       if (list->elements == NULL)
         goto fail;
       memcpy (list->elements, contents, count * sizeof (const void *));
diff --git a/lib/glob.c b/lib/glob.c
index 7ec066f..1857cd9 100644
--- a/lib/glob.c
+++ b/lib/glob.c
@@ -544,7 +544,7 @@ glob (pattern, flags, errfunc, pglob)
       else
         {
           size_t i;
-          pglob->gl_pathv = malloc ((pglob->gl_offs + 1) * sizeof (char *));
+          pglob->gl_pathv = nmalloc ((pglob->gl_offs + 1), sizeof (char *));
           if (pglob->gl_pathv == NULL)
             return GLOB_NOSPACE;
 
@@ -807,7 +807,7 @@ glob (pattern, flags, errfunc, pglob)
           char **new_gl_pathv;
 
           new_gl_pathv
-            = realloc (pglob->gl_pathv, (newcount + 1 + 1) * sizeof (char *));
+            = nrealloc (pglob->gl_pathv, (newcount + 1 + 1), sizeof (char *));
           if (new_gl_pathv == NULL)
             {
             nospace:
@@ -955,8 +955,8 @@ glob (pattern, flags, errfunc, pglob)
               int newcount = pglob->gl_pathc + pglob->gl_offs;
               char **new_gl_pathv;
 
-              new_gl_pathv = realloc (pglob->gl_pathv,
-                                      (newcount + 2) * sizeof (char *));
+              new_gl_pathv = nrealloc (pglob->gl_pathv, (newcount + 2),
+                                      sizeof (char *));
               if (new_gl_pathv == NULL)
                 {
                   globfree (&dirs);
@@ -1471,9 +1471,9 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
   if (nfound != 0)
     {
       char **new_gl_pathv
-        = realloc (pglob->gl_pathv,
-                   (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
-                   * sizeof (char *));
+        = nrealloc (pglob->gl_pathv,
+                   (pglob->gl_pathc + pglob->gl_offs + nfound + 1),
+                   sizeof (char *));
       result = 0;
 
       if (new_gl_pathv == NULL)
diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c
index 81908f0..1bc1dfc 100644
--- a/lib/glthread/lock.c
+++ b/lib/glthread/lock.c
@@ -703,7 +703,7 @@ gl_waitqueue_add (gl_waitqueue_t *wq)
     {
       unsigned int new_alloc = 2 * wq->alloc + 1;
       HANDLE *new_array =
-        (HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE));
+        (HANDLE *) nrealloc (wq->array, new_alloc, sizeof (HANDLE));
       if (new_array == NULL)
         /* No more memory.  */
         return INVALID_HANDLE_VALUE;
diff --git a/lib/group-member.c b/lib/group-member.c
index da01584..0f90909 100644
--- a/lib/group-member.c
+++ b/lib/group-member.c
@@ -53,10 +53,9 @@ get_group_info (struct group_info *gi)
   if (n_groups < 0)
     {
       int n_group_slots = getgroups (0, NULL);
-      if (0 <= n_group_slots
-          && ! xalloc_oversized (n_group_slots, sizeof *gi->group))
+      if (0 <= n_group_slots)
         {
-          gi->group = malloc (n_group_slots * sizeof *gi->group);
+          gi->group = nmalloc (n_group_slots, sizeof *gi->group);
           if (gi->group)
             n_groups = getgroups (n_group_slots, gi->group);
         }
diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c
index 2d82f45..cb3cb56 100644
--- a/lib/mgetgroups.c
+++ b/lib/mgetgroups.c
@@ -42,7 +42,7 @@ realloc_groupbuf (gid_t *g, size_t num)
       return NULL;
     }
 
-  return realloc (g, num * sizeof *g);
+  return nrealloc (g, num, sizeof *g);
 }
 
 /* Like getugroups, but store the result in malloc'd storage.
diff --git a/lib/putenv.c b/lib/putenv.c
index 5461273..5b7096b 100644
--- a/lib/putenv.c
+++ b/lib/putenv.c
@@ -179,7 +179,7 @@ putenv (char *string)
     {
       static char **last_environ = NULL;
       size_t size = ep - environ;
-      char **new_environ = malloc ((size + 2) * sizeof *new_environ);
+      char **new_environ = nmalloc ((size + 2), sizeof *new_environ);
       if (! new_environ)
         return -1;
       new_environ[0] = string;
diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c
index 25a2ff1..58b02eb 100644
--- a/lib/qcopy-acl.c
+++ b/lib/qcopy-acl.c
@@ -225,7 +225,7 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
           break;
         }
 
-      ace_entries = (ace_t *) malloc (ace_count * sizeof (ace_t));
+      ace_entries = (ace_t *) nmalloc (ace_count, sizeof (ace_t));
       if (ace_entries == NULL)
         {
           errno = ENOMEM;
@@ -278,7 +278,7 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
           break;
         }
 
-      entries = (aclent_t *) malloc (count * sizeof (aclent_t));
+      entries = (aclent_t *) nmalloc (count, sizeof (aclent_t));
       if (entries == NULL)
         {
           errno = ENOMEM;
diff --git a/lib/qset-acl.c b/lib/qset-acl.c
index 7bde2c1..6398ec3 100644
--- a/lib/qset-acl.c
+++ b/lib/qset-acl.c
@@ -232,7 +232,7 @@ qset_acl (char const *name, int desc, mode_t mode)
                 return -1;
               }
             alloc = 2 * alloc; /* <= alloc_max */
-            entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
+            entries = malloced = (ace_t *) nmalloc (alloc, sizeof (ace_t));
             if (entries == NULL)
               {
                 errno = ENOMEM;
diff --git a/lib/regexec.c b/lib/regexec.c
index 21d14ad..d9b284a 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -3425,7 +3425,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
   else
     {
       dest_states = (re_dfastate_t **)
-	malloc (ndests * 3 * sizeof (re_dfastate_t *));
+	nmalloc (ndests * 3, sizeof (re_dfastate_t *));
       if (BE (dest_states == NULL, 0))
 	{
 out_free:
diff --git a/lib/safe-alloc.c b/lib/safe-alloc.c
index 510e06b..4a83fde 100644
--- a/lib/safe-alloc.c
+++ b/lib/safe-alloc.c
@@ -68,16 +68,10 @@ safe_alloc_alloc_n (void *ptrptr, size_t size, size_t count, int zeroed)
       return 0;
     }
 
-  if (safe_alloc_oversized (count, size))
-    {
-      errno = ENOMEM;
-      return -1;
-    }
-
   if (zeroed)
     *(void **) ptrptr = calloc (count, size);
   else
-    *(void **) ptrptr = malloc (count * size);
+    *(void **) ptrptr = nmalloc (count, size);
 
   if (*(void **) ptrptr == NULL)
     return -1;
@@ -108,12 +102,8 @@ safe_alloc_realloc_n (void *ptrptr, size_t size, size_t count)
       *(void **) ptrptr = NULL;
       return 0;
     }
-  if (safe_alloc_oversized (count, size))
-    {
-      errno = ENOMEM;
-      return -1;
-    }
-  tmp = realloc (*(void **) ptrptr, size * count);
+
+  tmp = nrealloc (*(void **) ptrptr, size, count);
   if (!tmp)
     return -1;
   *(void **) ptrptr = tmp;
diff --git a/lib/scandir.c b/lib/scandir.c
index eccbc74..8b78b54 100644
--- a/lib/scandir.c
+++ b/lib/scandir.c
@@ -142,7 +142,7 @@ SCANDIR (const char *dir,
                 vsize = 10;
               else
                 vsize *= 2;
-              new = (DIRENT_TYPE **) realloc (v, vsize * sizeof (*v));
+              new = (DIRENT_TYPE **) nrealloc (v, vsize, sizeof (*v));
               if (new == NULL)
                 break;
               v = new;
diff --git a/lib/setenv.c b/lib/setenv.c
index 995a0f2..bc0bf64 100644
--- a/lib/setenv.c
+++ b/lib/setenv.c
@@ -144,8 +144,8 @@ __add_to_environ (const char *name, const char *value, const char *combined,
       /* We allocated this space; we can extend it.  */
       new_environ =
         (char **) (last_environ == NULL
-                   ? malloc ((size + 2) * sizeof (char *))
-                   : realloc (last_environ, (size + 2) * sizeof (char *)));
+                   ? nmalloc ((size + 2), sizeof (char *))
+                   : nrealloc (last_environ, (size + 2), sizeof (char *)));
       if (new_environ == NULL)
         {
           /* It's easier to set errno to ENOMEM than to rely on the
diff --git a/lib/spawn_faction_init.c b/lib/spawn_faction_init.c
index cf1d0a6..e108c64 100644
--- a/lib/spawn_faction_init.c
+++ b/lib/spawn_faction_init.c
@@ -32,8 +32,8 @@ int
 __posix_spawn_file_actions_realloc (posix_spawn_file_actions_t *file_actions)
 {
   int newalloc = file_actions->_allocated + 8;
-  void *newmem = realloc (file_actions->_actions,
-                          newalloc * sizeof (struct __spawn_action));
+  void *newmem = nrealloc (file_actions->_actions, newalloc,
+                          sizeof (struct __spawn_action));
 
   if (newmem == NULL)
     /* Not enough memory.  */
diff --git a/lib/uniconv/u16-conv-to-enc.c b/lib/uniconv/u16-conv-to-enc.c
index d4c0665..6867f4c 100644
--- a/lib/uniconv/u16-conv-to-enc.c
+++ b/lib/uniconv/u16-conv-to-enc.c
@@ -109,10 +109,10 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
           if (length + 6 > allocated)
             allocated = length + 6;
           if (result == resultbuf || result == NULL)
-            memory = (DST_UNIT *) malloc (allocated * sizeof (DST_UNIT));
+            memory = (DST_UNIT *) nmalloc (allocated, sizeof (DST_UNIT));
           else
             memory =
-              (DST_UNIT *) realloc (result, allocated * sizeof (DST_UNIT));
+              (DST_UNIT *) nrealloc (result, allocated, sizeof (DST_UNIT));
 
           if (memory == NULL)
             {
@@ -150,7 +150,7 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
       /* Shrink the allocated memory if possible.  */
       DST_UNIT *memory;
 
-      memory = (DST_UNIT *) realloc (result, length * sizeof (DST_UNIT));
+      memory = (DST_UNIT *) nrealloc (result, length, sizeof (DST_UNIT));
       if (memory != NULL)
         result = memory;
     }
diff --git a/lib/unigbrk/ulc-grapheme-breaks.c b/lib/unigbrk/ulc-grapheme-breaks.c
index d9d2f5c..02f8ebf 100644
--- a/lib/unigbrk/ulc-grapheme-breaks.c
+++ b/lib/unigbrk/ulc-grapheme-breaks.c
@@ -80,7 +80,7 @@ ulc_grapheme_breaks (const char *s, size_t n, char *p)
         {
           /* Convert the string to UTF-8 and build a translation table
              from offsets into s to offsets into the translated string.  */
-          size_t *offsets = (size_t *) malloc (n * sizeof (size_t));
+          size_t *offsets = (size_t *) nmalloc (n, sizeof (size_t));
 
           if (offsets != NULL)
             {
diff --git a/lib/unilbrk/ulc-possible-linebreaks.c b/lib/unilbrk/ulc-possible-linebreaks.c
index 41daddd..8684326 100644
--- a/lib/unilbrk/ulc-possible-linebreaks.c
+++ b/lib/unilbrk/ulc-possible-linebreaks.c
@@ -52,7 +52,7 @@ ulc_possible_linebreaks (const char *s, size_t n, const char *encoding,
         {
           /* Convert the string to UTF-8 and build a translation table
              from offsets into s to offsets into the translated string.  */
-          size_t *offsets = (size_t *) malloc (n * sizeof (size_t));
+          size_t *offsets = (size_t *) nmalloc (n, sizeof (size_t));
 
           if (offsets != NULL)
             {
diff --git a/lib/unilbrk/ulc-width-linebreaks.c b/lib/unilbrk/ulc-width-linebreaks.c
index e39f853..95ec686 100644
--- a/lib/unilbrk/ulc-width-linebreaks.c
+++ b/lib/unilbrk/ulc-width-linebreaks.c
@@ -54,7 +54,7 @@ ulc_width_linebreaks (const char *s, size_t n,
         {
           /* Convert the string to UTF-8 and build a translation table
              from offsets into s to offsets into the translated string.  */
-          size_t *offsets = (size_t *) malloc (n * sizeof (size_t));
+          size_t *offsets = (size_t *) nmalloc (n, sizeof (size_t));
 
           if (offsets != NULL)
             {
diff --git a/lib/uninorm/uninorm-filter.c b/lib/uninorm/uninorm-filter.c
index 2559cc9..fd1f886 100644
--- a/lib/uninorm/uninorm-filter.c
+++ b/lib/uninorm/uninorm-filter.c
@@ -240,7 +240,8 @@ uninorm_filter_write (struct uninorm_filter *filter, ucs4_t uc_arg)
               abort ();
             new_sortbuf =
               (struct ucs4_with_ccc *)
-              malloc (2 * filter->sortbuf_allocated * sizeof (struct ucs4_with_ccc));
+              nmalloc (2 * filter->sortbuf_allocated,
+                      sizeof (struct ucs4_with_ccc));
             if (new_sortbuf == NULL)
               {
                 /* errno is ENOMEM. */
diff --git a/lib/unistr/u16-to-u32.c b/lib/unistr/u16-to-u32.c
index d279f6a..067f85c 100644
--- a/lib/unistr/u16-to-u32.c
+++ b/lib/unistr/u16-to-u32.c
@@ -77,10 +77,10 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
           if (length + 1 > allocated)
             allocated = length + 1;
           if (result == resultbuf || result == NULL)
-            memory = (DST_UNIT *) malloc (allocated * sizeof (DST_UNIT));
+            memory = (DST_UNIT *) nmalloc (allocated, sizeof (DST_UNIT));
           else
             memory =
-              (DST_UNIT *) realloc (result, allocated * sizeof (DST_UNIT));
+              (DST_UNIT *) nrealloc (result, allocated, sizeof (DST_UNIT));
 
           if (memory == NULL)
             {
@@ -115,7 +115,7 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
       /* Shrink the allocated memory if possible.  */
       DST_UNIT *memory;
 
-      memory = (DST_UNIT *) realloc (result, length * sizeof (DST_UNIT));
+      memory = (DST_UNIT *) nrealloc (result, length, sizeof (DST_UNIT));
       if (memory != NULL)
         result = memory;
     }
diff --git a/lib/unistr/u16-to-u8.c b/lib/unistr/u16-to-u8.c
index c589727..93bd5f9 100644
--- a/lib/unistr/u16-to-u8.c
+++ b/lib/unistr/u16-to-u8.c
@@ -85,10 +85,10 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
           if (length + 6 > allocated)
             allocated = length + 6;
           if (result == resultbuf || result == NULL)
-            memory = (DST_UNIT *) malloc (allocated * sizeof (DST_UNIT));
+            memory = (DST_UNIT *) nmalloc (allocated, sizeof (DST_UNIT));
           else
             memory =
-              (DST_UNIT *) realloc (result, allocated * sizeof (DST_UNIT));
+              (DST_UNIT *) nrealloc (result, allocated, sizeof (DST_UNIT));
 
           if (memory == NULL)
             {
@@ -126,7 +126,7 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
       /* Shrink the allocated memory if possible.  */
       DST_UNIT *memory;
 
-      memory = (DST_UNIT *) realloc (result, length * sizeof (DST_UNIT));
+      memory = (DST_UNIT *) nrealloc (result, length, sizeof (DST_UNIT));
       if (memory != NULL)
         result = memory;
     }
diff --git a/lib/unistr/u32-to-u16.c b/lib/unistr/u32-to-u16.c
index cf24783..dbb3a4f 100644
--- a/lib/unistr/u32-to-u16.c
+++ b/lib/unistr/u32-to-u16.c
@@ -79,10 +79,10 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
           if (length + 2 > allocated)
             allocated = length + 2;
           if (result == resultbuf || result == NULL)
-            memory = (DST_UNIT *) malloc (allocated * sizeof (DST_UNIT));
+            memory = (DST_UNIT *) nmalloc (allocated, sizeof (DST_UNIT));
           else
             memory =
-              (DST_UNIT *) realloc (result, allocated * sizeof (DST_UNIT));
+              (DST_UNIT *) nrealloc (result, allocated, sizeof (DST_UNIT));
 
           if (memory == NULL)
             {
@@ -120,7 +120,7 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
       /* Shrink the allocated memory if possible.  */
       DST_UNIT *memory;
 
-      memory = (DST_UNIT *) realloc (result, length * sizeof (DST_UNIT));
+      memory = (DST_UNIT *) nrealloc (result, length, sizeof (DST_UNIT));
       if (memory != NULL)
         result = memory;
     }
diff --git a/lib/unistr/u32-to-u8.c b/lib/unistr/u32-to-u8.c
index 702279f..5769db0 100644
--- a/lib/unistr/u32-to-u8.c
+++ b/lib/unistr/u32-to-u8.c
@@ -79,10 +79,10 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
           if (length + 6 > allocated)
             allocated = length + 6;
           if (result == resultbuf || result == NULL)
-            memory = (DST_UNIT *) malloc (allocated * sizeof (DST_UNIT));
+            memory = (DST_UNIT *) nmalloc (allocated, sizeof (DST_UNIT));
           else
             memory =
-              (DST_UNIT *) realloc (result, allocated * sizeof (DST_UNIT));
+              (DST_UNIT *) nrealloc (result, allocated, sizeof (DST_UNIT));
 
           if (memory == NULL)
             {
@@ -120,7 +120,7 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
       /* Shrink the allocated memory if possible.  */
       DST_UNIT *memory;
 
-      memory = (DST_UNIT *) realloc (result, length * sizeof (DST_UNIT));
+      memory = (DST_UNIT *) nrealloc (result, length, sizeof (DST_UNIT));
       if (memory != NULL)
         result = memory;
     }
diff --git a/lib/unistr/u8-to-u16.c b/lib/unistr/u8-to-u16.c
index 528d463..2df138e 100644
--- a/lib/unistr/u8-to-u16.c
+++ b/lib/unistr/u8-to-u16.c
@@ -85,10 +85,10 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
           if (length + 2 > allocated)
             allocated = length + 2;
           if (result == resultbuf || result == NULL)
-            memory = (DST_UNIT *) malloc (allocated * sizeof (DST_UNIT));
+            memory = (DST_UNIT *) nmalloc (allocated, sizeof (DST_UNIT));
           else
             memory =
-              (DST_UNIT *) realloc (result, allocated * sizeof (DST_UNIT));
+              (DST_UNIT *) nrealloc (result, allocated, sizeof (DST_UNIT));
 
           if (memory == NULL)
             {
@@ -126,7 +126,7 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
       /* Shrink the allocated memory if possible.  */
       DST_UNIT *memory;
 
-      memory = (DST_UNIT *) realloc (result, length * sizeof (DST_UNIT));
+      memory = (DST_UNIT *) nrealloc (result, length, sizeof (DST_UNIT));
       if (memory != NULL)
         result = memory;
     }
diff --git a/lib/unistr/u8-to-u32.c b/lib/unistr/u8-to-u32.c
index cbd0b9e..7c3be02 100644
--- a/lib/unistr/u8-to-u32.c
+++ b/lib/unistr/u8-to-u32.c
@@ -77,10 +77,10 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
           if (length + 1 > allocated)
             allocated = length + 1;
           if (result == resultbuf || result == NULL)
-            memory = (DST_UNIT *) malloc (allocated * sizeof (DST_UNIT));
+            memory = (DST_UNIT *) nmalloc (allocated, sizeof (DST_UNIT));
           else
             memory =
-              (DST_UNIT *) realloc (result, allocated * sizeof (DST_UNIT));
+              (DST_UNIT *) nrealloc (result, allocated, sizeof (DST_UNIT));
 
           if (memory == NULL)
             {
@@ -115,7 +115,7 @@ FUNC (const SRC_UNIT *s, size_t n, DST_UNIT *resultbuf, size_t *lengthp)
       /* Shrink the allocated memory if possible.  */
       DST_UNIT *memory;
 
-      memory = (DST_UNIT *) realloc (result, length * sizeof (DST_UNIT));
+      memory = (DST_UNIT *) nrealloc (result, length, sizeof (DST_UNIT));
       if (memory != NULL)
         result = memory;
     }
diff --git a/lib/uniwbrk/ulc-wordbreaks.c b/lib/uniwbrk/ulc-wordbreaks.c
index 17d06ad..e5702c8 100644
--- a/lib/uniwbrk/ulc-wordbreaks.c
+++ b/lib/uniwbrk/ulc-wordbreaks.c
@@ -54,7 +54,7 @@ ulc_wordbreaks (const char *s, size_t n, char *p)
         {
           /* Convert the string to UTF-8 and build a translation table
              from offsets into s to offsets into the translated string.  */
-          size_t *offsets = (size_t *) malloc (n * sizeof (size_t));
+          size_t *offsets = (size_t *) nmalloc (n, sizeof (size_t));
 
           if (offsets != NULL)
             {
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 21f9169..4c0da59 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -376,7 +376,7 @@ multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
       size_t k, i, j;
 
       dlen = len1 + len2;
-      dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
+      dp = (mp_limb_t *) nmalloc (dlen, sizeof (mp_limb_t));
       if (dp == NULL)
         return NULL;
       for (k = len2; k > 0; )
@@ -479,7 +479,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
   /* Allocate room for a_len+2 digits.
      (Need a_len+1 digits for the real division and 1 more digit for the
      final rounding of q.)  */
-  roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
+  roomptr = (mp_limb_t *) nmalloc ((a_len + 2), sizeof (mp_limb_t));
   if (roomptr == NULL)
     return NULL;
 
@@ -612,7 +612,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
          Copy b, shifting it left by s bits.  */
       if (s > 0)
         {
-          tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
+          tmp_roomptr = (mp_limb_t *) nmalloc (b_len, sizeof (mp_limb_t));
           if (tmp_roomptr == NULL)
             {
               free (roomptr);
@@ -906,7 +906,7 @@ decode_long_double (long double x, int *ep, mpn_t *mp)
 
   /* Allocate memory for result.  */
   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
-  m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
+  m.limbs = (mp_limb_t *) nmalloc (m.nlimbs, sizeof (mp_limb_t));
   if (m.limbs == NULL)
     return NULL;
   /* Split into exponential part and mantissa.  */
@@ -994,7 +994,7 @@ decode_double (double x, int *ep, mpn_t *mp)
 
   /* Allocate memory for result.  */
   m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
-  m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
+  m.limbs = (mp_limb_t *) nmalloc (m.nlimbs, sizeof (mp_limb_t));
   if (m.limbs == NULL)
     return NULL;
   /* Split into exponential part and mantissa.  */
@@ -1105,9 +1105,9 @@ scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
      sign.  2.322 is slightly larger than log(5)/log(2).  */
   abs_n = (n >= 0 ? n : -n);
   abs_s = (s >= 0 ? s : -s);
-  pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
-                                    + abs_s / GMP_LIMB_BITS + 1)
-                                   * sizeof (mp_limb_t));
+  pow5_ptr = (mp_limb_t *) nmalloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS))
+					   + 1 + abs_s / GMP_LIMB_BITS + 1),
+				    sizeof (mp_limb_t));
   if (pow5_ptr == NULL)
     {
       free (memory);
@@ -1228,8 +1228,8 @@ scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
              Multiply m with 2^s, then divide by pow5.  */
           mpn_t numerator;
           mp_limb_t *num_ptr;
-          num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
-                                          * sizeof (mp_limb_t));
+          num_ptr = (mp_limb_t *) nmalloc ((m.nlimbs + s_limbs + 1),
+                                          sizeof (mp_limb_t));
           if (num_ptr == NULL)
             {
               free (pow5_ptr);
diff --git a/lib/wait-process.c b/lib/wait-process.c
index 17a2430..e4b350a 100644
--- a/lib/wait-process.c
+++ b/lib/wait-process.c
@@ -144,7 +144,7 @@ register_slave_subprocess (pid_t child)
       size_t new_slaves_allocated = 2 * slaves_allocated;
       slaves_entry_t *new_slaves =
         (slaves_entry_t *)
-        malloc (new_slaves_allocated * sizeof (slaves_entry_t));
+        nmalloc (new_slaves_allocated, sizeof (slaves_entry_t));
       if (new_slaves == NULL)
         {
           /* xalloc_die() will call exit() which will invoke cleanup_slaves().


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-03 12:13 [PATCH 1/2] Add nmalloc, NMALLOC et al Ondřej Bílka
  2013-11-03 12:28 ` [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows Ondřej Bílka
  2013-11-03 20:04 ` [PATCH 1/2] Add nmalloc, NMALLOC et al Paul Eggert
@ 2013-11-06 12:27 ` Richard W.M. Jones
  2013-11-06 12:37   ` Ondřej Bílka
  2013-11-06 18:57   ` Paul Eggert
  2 siblings, 2 replies; 12+ messages in thread
From: Richard W.M. Jones @ 2013-11-06 12:27 UTC (permalink / raw
  To: Ondřej Bílka; +Cc: bug-gnulib


On Sun, Nov 03, 2013 at 01:13:35PM +0100, Ondřej Bílka wrote:
> Hi,
> 
> For syncing with libc refactoring of malloc following patch adds for
> consistency nmalloc variants.
> 
> These will make overflow checking of common allocations automatic as in
> next patch.
> 
> 	* lib/xalloc.h (NMALLOC, NREALLOC, nmalloc, nrealloc): Add.

Is nmalloc a standard (or proposed standard)?  It's not in glibc and
various web searches don't turn up much.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming blog: http://rwmj.wordpress.com
Fedora now supports 80 OCaml packages (the OPEN alternative to F#)


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-06 12:27 ` Richard W.M. Jones
@ 2013-11-06 12:37   ` Ondřej Bílka
  2013-11-06 18:57   ` Paul Eggert
  1 sibling, 0 replies; 12+ messages in thread
From: Ondřej Bílka @ 2013-11-06 12:37 UTC (permalink / raw
  To: Richard W.M. Jones; +Cc: bug-gnulib

On Wed, Nov 06, 2013 at 12:27:57PM +0000, Richard W.M. Jones wrote:
> 
> On Sun, Nov 03, 2013 at 01:13:35PM +0100, Ondřej Bílka wrote:
> > Hi,
> > 
> > For syncing with libc refactoring of malloc following patch adds for
> > consistency nmalloc variants.
> > 
> > These will make overflow checking of common allocations automatic as in
> > next patch.
> > 
> > 	* lib/xalloc.h (NMALLOC, NREALLOC, nmalloc, nrealloc): Add.
> 
> Is nmalloc a standard (or proposed standard)?  It's not in glibc and
> various web searches don't turn up much.
>
No, they are primary for internal use.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-06 12:27 ` Richard W.M. Jones
  2013-11-06 12:37   ` Ondřej Bílka
@ 2013-11-06 18:57   ` Paul Eggert
  2013-11-08 10:42     ` Richard W.M. Jones
  1 sibling, 1 reply; 12+ messages in thread
From: Paul Eggert @ 2013-11-06 18:57 UTC (permalink / raw
  To: bug-gnulib

On 11/06/2013 04:27 AM, Richard W.M. Jones wrote:
> Is nmalloc a standard (or proposed standard)?

No, but it should be, because of the integer overflow problem.
Is that something you can get the ball rolling on?
Standardization committees are not my strong suit.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] Add nmalloc, NMALLOC et al.
  2013-11-06 18:57   ` Paul Eggert
@ 2013-11-08 10:42     ` Richard W.M. Jones
  0 siblings, 0 replies; 12+ messages in thread
From: Richard W.M. Jones @ 2013-11-08 10:42 UTC (permalink / raw
  To: Paul Eggert; +Cc: Eric Blake, bug-gnulib

On Wed, Nov 06, 2013 at 10:57:41AM -0800, Paul Eggert wrote:
> On 11/06/2013 04:27 AM, Richard W.M. Jones wrote:
> > Is nmalloc a standard (or proposed standard)?
> 
> No, but it should be, because of the integer overflow problem.
> Is that something you can get the ball rolling on?
> Standardization committees are not my strong suit.

Eric Blake would be the one to ask, I think.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines.  Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-11-08 10:42 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-03 12:13 [PATCH 1/2] Add nmalloc, NMALLOC et al Ondřej Bílka
2013-11-03 12:28 ` [SPATCH 2/2] Rewrite malloc/malloca to one avoiding overflows Ondřej Bílka
2013-11-03 20:09   ` Paul Eggert
2013-11-03 21:25     ` Ondřej Bílka
2013-11-03 20:04 ` [PATCH 1/2] Add nmalloc, NMALLOC et al Paul Eggert
2013-11-03 20:13   ` Ondřej Bílka
2013-11-03 20:17     ` Paul Eggert
2013-11-03 20:36     ` Ondřej Bílka
2013-11-06 12:27 ` Richard W.M. Jones
2013-11-06 12:37   ` Ondřej Bílka
2013-11-06 18:57   ` Paul Eggert
2013-11-08 10:42     ` Richard W.M. Jones

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).