libc: Add reallocarray() from OpenBSD.
authorSascha Wildner <saw@online.de>
Sat, 12 Jan 2019 22:37:36 +0000 (23:37 +0100)
committerSascha Wildner <saw@online.de>
Sat, 12 Jan 2019 22:39:18 +0000 (23:39 +0100)
It is useful for dhcpcd, mandoc and libssh. Also some dports might pick
it up. A few other dports have workarounds which, once reallocarray() is
in release too, can be removed.

Taken-from:     OpenBSD (manual page from FreeBSD)
Pointed-out-by: aly
include/stdlib.h
lib/libc/Versions.def
lib/libc/stdlib/Makefile.inc
lib/libc/stdlib/Symbol.map
lib/libc/stdlib/malloc.3
lib/libc/stdlib/reallocarray.3 [new file with mode: 0644]
lib/libc/stdlib/reallocarray.c [new file with mode: 0644]
sbin/dhcpcd/Makefile
sbin/dhcpcd/config.h
sys/sys/param.h

index e0daa6c..16637d1 100644 (file)
@@ -299,6 +299,7 @@ void         qsort_r(void *, size_t, size_t, void *,
                 int (*)(void *, const void *, const void *));
 int     radixsort(const unsigned char **, int, const unsigned char *,
                   unsigned int);
+void   *reallocarray(void *, size_t, size_t) __heedresult __alloc_size2(2, 3);
 void   *reallocf(void *, size_t) __heedresult __alloc_size(2);
 int     rpmatch(const char *);
 void    setprogname(const char *);
index 3bad35a..232608b 100644 (file)
@@ -41,6 +41,10 @@ DF502.0 {
 DF504.0 {
 } DF502.0;
 
+# version for DragonFly 5.5
+DF506.0 {
+} DF504.0;
+
 # This is our private namespace.  Any global interfaces that are
 # strictly for use only by other DragonFly applications and libraries
 # are listed here.  We use a separate namespace so we can write
index 7e6049b..a80357a 100644 (file)
@@ -12,7 +12,8 @@ MISRCS+=a64l.c abort.c abs.c atexit.c aligned_alloc.c \
        getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c \
        insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
        merge.c ptsname.c qsort.c qsort_r.c quick_exit.c \
-       radixsort.c rand.c random.c reallocf.c realpath.c remque.c \
+       radixsort.c rand.c random.c \
+       reallocarray.c reallocf.c realpath.c remque.c \
        strfmon.c strsuftoll.c strtoimax.c \
        strtol.c strtoll.c strtonum.c strtoq.c strtoul.c strtoull.c \
        strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
@@ -40,7 +41,7 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 \
        hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
        lsearch.3 malloc.3 memory.3 posix_memalign.3 posix_openpt.3 \
        ptsname.3 qsort.3 quick_exit.3 \
-       radixsort.3 rand.3 random.3 realpath.3 \
+       radixsort.3 rand.3 random.3 realpath.3 reallocarray.3 \
        strfmon.3 strsuftoll.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
        tsearch.3
 
index f270ddf..efb0c2e 100644 (file)
@@ -116,6 +116,10 @@ DF504.0 {
     strsuftollx;
 };
 
+DF506.0 {
+    reallocarray;
+};
+
 /*
  * ignore WEAK:  __pthread_cxa_finalize;
  */
index 4863da9..617fd8d 100644 (file)
@@ -34,7 +34,7 @@
 .\"     @(#)malloc.3   8.1 (Berkeley) 6/4/93
 .\" $FreeBSD: src/lib/libc/stdlib/malloc.3,v 1.73 2007/06/15 22:32:33 jasone Exp $
 .\"
-.Dd May 21, 2010
+.Dd January 12, 2019
 .Dt MALLOC 3
 .Os
 .Sh NAME
@@ -312,7 +312,8 @@ and the process will dump core.
 .Xr emalloc 3 ,
 .Xr getpagesize 3 ,
 .Xr memory 3 ,
-.Xr posix_memalign 3
+.Xr posix_memalign 3 ,
+.Xr reallocarray 3
 .Sh STANDARDS
 The
 .Fn malloc ,
diff --git a/lib/libc/stdlib/reallocarray.3 b/lib/libc/stdlib/reallocarray.3
new file mode 100644 (file)
index 0000000..dbf16d9
--- /dev/null
@@ -0,0 +1,142 @@
+.\" Copyright (c) 1980, 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the American National Standards Committee X3, on Information
+.\" Processing Systems.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/lib/libc/stdlib/reallocarray.3 282472 2015-05-05 10:44:17Z pluknet $
+.\"
+.Dd January 12, 2019
+.Dt REALLOCARRAY 3
+.Os
+.Sh NAME
+.Nm reallocarray
+.Nd memory reallocation function
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft void *
+.Fn reallocarray "void *ptr" "size_t number" "size_t size"
+.Sh DESCRIPTION
+The
+.Fn reallocarray
+function is similar to the
+.Fn realloc
+function
+except it operates on
+.Fa number
+members of size
+.Fa size
+and checks for integer overflow in the calculation
+.Fa number
+*
+.Fa size .
+.Sh RETURN VALUES
+The
+.Fn reallocarray
+function returns a pointer to the allocated space; otherwise, a
+.Dv NULL
+pointer is returned and
+.Va errno
+is set to
+.Er ENOMEM .
+.Sh EXAMPLES
+Consider
+.Fn reallocarray
+when there is multiplication in the
+.Fa size
+argument of
+.Fn malloc
+or
+.Fn realloc .
+For example, avoid this common idiom as it may lead to integer overflow:
+.Bd -literal -offset indent
+if ((p = malloc(num * size)) == NULL)
+       err(1, "malloc");
+.Ed
+.Pp
+A drop-in replacement is the
+.Ox
+extension
+.Fn reallocarray :
+.Bd -literal -offset indent
+if ((p = reallocarray(NULL, num, size)) == NULL)
+       err(1, "reallocarray");
+.Ed
+.Pp
+When using
+.Fn realloc ,
+be careful to avoid the following idiom:
+.Bd -literal -offset indent
+size += 50;
+if ((p = realloc(p, size)) == NULL)
+       return (NULL);
+.Ed
+.Pp
+Do not adjust the variable describing how much memory has been allocated
+until the allocation has been successful.
+This can cause aberrant program behavior if the incorrect size value is used.
+In most cases, the above sample will also result in a leak of memory.
+As stated earlier, a return value of
+.Dv NULL
+indicates that the old object still remains allocated.
+Better code looks like this:
+.Bd -literal -offset indent
+newsize = size + 50;
+if ((newp = realloc(p, newsize)) == NULL) {
+       free(p);
+       p = NULL;
+       size = 0;
+       return (NULL);
+}
+p = newp;
+size = newsize;
+.Ed
+.Pp
+As with
+.Fn malloc ,
+it is important to ensure the new size value will not overflow;
+i.e. avoid allocations like the following:
+.Bd -literal -offset indent
+if ((newp = realloc(p, num * size)) == NULL) {
+       ...
+.Ed
+.Pp
+Instead, use
+.Fn reallocarray :
+.Bd -literal -offset indent
+if ((newp = reallocarray(p, num, size)) == NULL) {
+       ...
+.Ed
+.Sh SEE ALSO
+.Xr realloc 3
+.Sh HISTORY
+The
+.Fn reallocarray
+function first appeared in
+.Ox 5.6
+and
+.Fx 11.0 .
diff --git a/lib/libc/stdlib/reallocarray.c b/lib/libc/stdlib/reallocarray.c
new file mode 100644 (file)
index 0000000..f0521ca
--- /dev/null
@@ -0,0 +1,38 @@
+/*     $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $       */
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@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.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+/*
+ * 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))
+
+void *
+reallocarray(void *ptr, size_t number, size_t size)
+{
+       if ((number >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+           number > 0 && SIZE_MAX / number < size) {
+               errno = ENOMEM;
+               return NULL;
+       }
+       return realloc(ptr, size * number);
+}
index 601c577..5ab6c20 100644 (file)
@@ -26,7 +26,7 @@ CFLAGS+=      -DDHCP6
 SRCS+=         dhcp6.c
 
 .PATH:         ${DISTDIR}/compat
-SRCS+=         pidfile.c reallocarray.c strtoi.c strtou.c
+SRCS+=         pidfile.c strtoi.c strtou.c
 .PATH:         ${DISTDIR}/compat/crypt
 SRCS+=         hmac.c
 
index 27a5f71..095d3e3 100644 (file)
@@ -8,7 +8,6 @@
 #define        TAILQ_FOREACH_SAFE      TAILQ_FOREACH_MUTABLE
 #define        HAVE_KQUEUE
 #define        HAVE_REALLOCARRAY
-#include                       "compat/reallocarray.h"
 #include                       "compat/pidfile.h"
 #include                       "compat/strtoi.h"
 #define        HAVE_MD5_H
index b541a78..2beff21 100644 (file)
  * 500317 - add wait6() and waitid() syscalls
  * 500400 - 5.4 release
  * 500500 - 5.5 development
+ * 500501 - reallocarray() added to libc
  */
 #undef __DragonFly_version
-#define __DragonFly_version 500500     /* propagated to newvers */
+#define __DragonFly_version 500501     /* propagated to newvers */
 
 #include <sys/_null.h>