libbsd: Branch 'master' - 2 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Jan 1 17:20:19 UTC 2021
COPYING | 4
include/bsd/stdlib.h | 2
man/Makefile.am | 2
man/freezero.3bsd | 1
man/reallocarray.3bsd | 256 ++++++++++++++++++++++++++++++++++++++++++-------
man/recallocarray.3bsd | 1
src/Makefile.am | 2
src/freezero.c | 30 +++++
src/libbsd.map | 3
src/local-elf.h | 2
src/recallocarray.c | 80 +++++++++++++++
11 files changed, 347 insertions(+), 36 deletions(-)
New commits:
commit 01f0d1ea1e71f1018a009ebd9203dd48e6d90c45
Author: Faidon Liambotis <paravoid at debian.org>
Date: Thu Dec 31 12:46:03 2020 +0200
Add recallocarray() and freezero() from OpenBSD
Add recallocarray(), introduced in OpenBSD 6.1, and freezero(),
introduced in OpenBSD 6.2. The former is imported as-is from OpenBSD,
while the latter is the non-malloc-internal branch of the same code (and
also the OpenSSH portable variant).
Both of these originated in OpenBSD, but have also been implemented by
IllumOS, cf. https://www.illumos.org/issues/8546
Documentation for these functions is in malloc(3) upstream, the relevant
parts of which were previously imported in reallocarray(3bsd). Update
reallocarray(3bsd) with the changes that were introduced since, and add
the relevant bits for recallocarray() and freezero(), plus aliases.
[guillem at hadrons.org: Update copyright in COPYING. ]
Closes: !10
Signed-off-by: Guillem Jover <guillem at hadrons.org>
diff --git a/COPYING b/COPYING
index 333ed40..d3899a9 100644
--- a/COPYING
+++ b/COPYING
@@ -368,6 +368,7 @@ Files:
src/arc4random_unix.h
src/arc4random_win.h
src/closefrom.c
+ src/freezero.c
src/getentropy_aix.c
src/getentropy_bsd.c
src/getentropy_hpux.c
@@ -378,6 +379,7 @@ Files:
src/getentropy_win.c
src/readpassphrase.c
src/reallocarray.c
+ src/recallocarray.c
src/strlcat.c
src/strlcpy.c
Copyright:
@@ -389,7 +391,7 @@ Copyright:
Todd C. Miller <Todd.Miller at courtesan.com>
Copyright © 2004 Ted Unangst
Copyright © 2008 Damien Miller <djm at openbsd.org>
- Copyright © 2008 Otto Moerbeek <otto at drijf.net>
+ Copyright © 2008, 2010-2011, 2016-2017 Otto Moerbeek <otto at drijf.net>
Copyright © 2013 Markus Friedl <markus at openbsd.org>
Copyright © 2014 Bob Beck <beck at obtuse.com>
Copyright © 2014 Brent Cook <bcook at openbsd.org>
diff --git a/include/bsd/stdlib.h b/include/bsd/stdlib.h
index ea3251d..2bee974 100644
--- a/include/bsd/stdlib.h
+++ b/include/bsd/stdlib.h
@@ -75,6 +75,8 @@ void *reallocf(void *ptr, size_t size);
(defined(__GLIBC__) && (!__GLIBC_PREREQ(2, 26) || !defined(_GNU_SOURCE)))
void *reallocarray(void *ptr, size_t nmemb, size_t size);
#endif
+void *recallocarray(void *ptr, size_t oldnmemb, size_t nmemb, size_t size);
+void freezero(void *ptr, size_t size);
long long strtonum(const char *nptr, long long minval, long long maxval,
const char **errstr);
diff --git a/man/Makefile.am b/man/Makefile.am
index e3b27da..4c7ed05 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -165,6 +165,7 @@ dist_man_MANS = \
fgetln.3bsd \
fgetwln.3bsd \
flopen.3bsd \
+ freezero.3bsd \
fmtcheck.3bsd \
fparseln.3bsd \
fpurge.3bsd \
@@ -195,6 +196,7 @@ dist_man_MANS = \
readpassphrase.3bsd \
reallocarray.3bsd \
reallocf.3bsd \
+ recallocarray.3bsd \
setmode.3bsd \
setproctitle.3bsd \
setproctitle_init.3bsd \
diff --git a/man/freezero.3bsd b/man/freezero.3bsd
new file mode 100644
index 0000000..09471db
--- /dev/null
+++ b/man/freezero.3bsd
@@ -0,0 +1 @@
+.so man3/reallocarray.3bsd
diff --git a/man/reallocarray.3bsd b/man/reallocarray.3bsd
index 1a37d33..704466c 100644
--- a/man/reallocarray.3bsd
+++ b/man/reallocarray.3bsd
@@ -30,13 +30,15 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $OpenBSD: malloc.3,v 1.78 2014/05/01 18:41:59 jmc Exp $
+.\" $OpenBSD: malloc.3,v 1.126 2019/09/14 13:16:50 otto Exp $
.\"
-.Dd $Mdocdate: May 1 2014 $
+.Dd $Mdocdate: September 14 2019 $
.Dt REALLOCARRAY 3bsd
.Os
.Sh NAME
-.Nm reallocarray
+.Nm reallocarray ,
+.Nm recallocarray ,
+.Nm freezero
.Nd memory allocation and deallocation
.Sh LIBRARY
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
@@ -49,59 +51,245 @@
for include usage.)
.Ft void *
.Fn reallocarray "void *ptr" "size_t nmemb" "size_t size"
+.Ft void *
+.Fn recallocarray "void *ptr" "size_t oldnmemb" "size_t nmemb" "size_t size"
+.Ft void
+.Fn freezero "void *ptr" "size_t size"
.Sh DESCRIPTION
.Pp
-When using
+Designed for safe allocation of arrays,
+the
+.Fn reallocarray
+function is similar to
+.Fn realloc
+except it operates on
+.Fa nmemb
+members of size
+.Fa size
+and checks for integer overflow in the calculation
+.Fa nmemb
+*
+.Fa size .
+.Pp
+Used for the allocation of memory holding sensitive data,
+the
+.Fn recallocarray
+function guarantees that memory becoming unallocated is explicitly
+.Em discarded ,
+meaning cached free objects are cleared with
+.Xr explicit_bzero 3 .
+.Pp
+The
+.Fn recallocarray
+function is similar to
+.Fn reallocarray
+except it ensures newly allocated memory is cleared similar to
+.Fn calloc .
+If
+.Fa ptr
+is
+.Dv NULL ,
+.Fa oldnmemb
+is ignored and the call is equivalent to
+.Fn calloc .
+If
+.Fa ptr
+is not
+.Dv NULL ,
+.Fa oldnmemb
+must be a value such that
+.Fa oldnmemb
+*
+.Fa size
+is the size of the earlier allocation that returned
+.Fa ptr ,
+otherwise the behavior is undefined.
+The
+.Fn freezero
+function is similar to the
+.Fn free
+function except it ensures memory is explicitly discarded.
+If
+.Fa ptr
+is
+.Dv NULL ,
+no action occurs.
+If
+.Fa ptr
+is not
+.Dv NULL ,
+the
+.Fa size
+argument must be equal to or smaller than the size of the earlier allocation
+that returned
+.Fa ptr .
+.Fn freezero
+guarantees the memory range starting at
+.Fa ptr
+with length
+.Fa size
+is discarded while deallocating the whole object originally allocated.
+.Sh RETURN VALUES
+The
+.Fn reallocarray
+and
+.Fn recallocarray
+functions return a pointer to the allocated space if successful; otherwise,
+a null pointer is returned and
+.Va errno
+is set to
+.Er ENOMEM .
+.Pp
+If multiplying
+.Fa nmemb
+and
+.Fa size
+results in integer overflow,
+.Fn reallocarray
+and
+.Fn recallocarray
+return
+.Dv NULL
+and set
+.Va errno
+to
+.Er ENOMEM .
+.Pp
+If
+.Fa ptr
+is not
+.Dv NULL
+and multiplying
+.Fa oldnmemb
+and
+.Fa size
+results in integer overflow
+.Fn recallocarray
+returns
+.Dv NULL
+and sets
+.Va errno
+to
+.Er EINVAL .
+.Sh IDIOMS
+Consider
+.Fn calloc
+or the extensions
+.Fn reallocarray
+and
+.Fn recallocarray
+when there is multiplication in the
+.Fa size
+argument of
.Fn malloc
-be careful to avoid the following idiom:
+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");
+ err(1, NULL);
.Ed
.Pp
-The multiplication may lead to an integer overflow, which can
-be avoided using the extension
-.Fn reallocarray ,
-as follows:
+A drop-in replacement is
+.Fn reallocarray :
.Bd -literal -offset indent
if ((p = reallocarray(NULL, num, size)) == NULL)
- err(1, "malloc");
+ err(1, NULL);
.Ed
.Pp
-Alternatively
+Alternatively,
.Fn calloc
-is a more portable solution which comes with the cost of clearing memory.
+may be used at the cost of initialization overhead.
.Pp
-If
-.Fn malloc
-must be used, be sure to test for overflow:
+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
-if (size && num > SIZE_MAX / size) {
- errno = ENOMEM;
- err(1, "overflow");
+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
+.Pp
+Calling
+.Fn realloc
+with a
+.Dv NULL
+.Fa ptr
+is equivalent to calling
+.Fn malloc .
+Instead of this idiom:
+.Bd -literal -offset indent
+if (p == NULL)
+ newp = malloc(newsize);
+else
+ newp = realloc(p, newsize);
+.Ed
+.Pp
+Use the following:
+.Bd -literal -offset indent
+newp = realloc(p, newsize);
.Ed
.Pp
-The use of
-.Fn reallocarray
-or
-.Fn calloc
-is strongly encouraged when allocating multiple sized objects
-in order to avoid possible integer overflows.
-.Sh RETURN VALUES
The
-.Fn reallocarray
-function returns a pointer to the allocated space if successful; otherwise,
-a null pointer is returned and
-.Va errno
-is set to
-.Er ENOMEM .
+.Fn recallocarray
+function should be used for resizing objects containing sensitive data like
+keys.
+To avoid leaking information,
+it guarantees memory is cleared before placing it on the internal free list.
+Deallocation of such an object should be done by calling
+.Fn freezero .
+
.Sh SEE ALSO
.Xr malloc 3 ,
.Xr calloc 3 ,
.Xr alloca 3
.Sh HISTORY
+The
.Fn reallocarray
-appeared in
+function appeared in
.Ox 5.6 ,
-glibc 2.26.
+and glibc 2.26.
+The
+.Fn recallocarray
+function appeared in
+.Ox 6.1 .
+The
+.Fn freezero
+function appeared in
+.Ox 6.2 .
diff --git a/man/recallocarray.3bsd b/man/recallocarray.3bsd
new file mode 100644
index 0000000..09471db
--- /dev/null
+++ b/man/recallocarray.3bsd
@@ -0,0 +1 @@
+.so man3/reallocarray.3bsd
diff --git a/src/Makefile.am b/src/Makefile.am
index c4229cf..75cdecd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -86,6 +86,7 @@ libbsd_la_SOURCES = \
expand_number.c \
explicit_bzero.c \
fgetln.c \
+ freezero.c \
fgetwln.c \
flopen.c \
fmtcheck.c \
@@ -111,6 +112,7 @@ libbsd_la_SOURCES = \
readpassphrase.c \
reallocarray.c \
reallocf.c \
+ recallocarray.c \
setmode.c \
setproctitle.c \
strlcat.c \
diff --git a/src/freezero.c b/src/freezero.c
new file mode 100644
index 0000000..c565f43
--- /dev/null
+++ b/src/freezero.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: malloc.c,v 1.267 2020/11/23 15:42:11 otto Exp $ */
+/*
+ * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto at 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 <stdlib.h>
+#include <string.h>
+
+void
+freezero(void *ptr, size_t sz)
+{
+ /* This is legal. */
+ if (ptr == NULL)
+ return;
+
+ explicit_bzero(ptr, sz);
+ free(ptr);
+}
diff --git a/src/libbsd.map b/src/libbsd.map
index 1416c6f..f499f8e 100644
--- a/src/libbsd.map
+++ b/src/libbsd.map
@@ -184,4 +184,7 @@ LIBBSD_0.10.0 {
LIBBSD_0.11.0 {
strnvisx;
+
+ recallocarray;
+ freezero;
} LIBBSD_0.10.0;
diff --git a/src/recallocarray.c b/src/recallocarray.c
new file mode 100644
index 0000000..84d736b
--- /dev/null
+++ b/src/recallocarray.c
@@ -0,0 +1,80 @@
+/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */
+/*
+ * Copyright (c) 2008, 2017 Otto Moerbeek <otto at 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 <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.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 *
+recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
+{
+ size_t oldsize, newsize;
+ void *newptr;
+
+ if (ptr == NULL)
+ return calloc(newnmemb, size);
+
+ if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ newnmemb > 0 && SIZE_MAX / newnmemb < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ newsize = newnmemb * size;
+
+ if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
+ errno = EINVAL;
+ return NULL;
+ }
+ oldsize = oldnmemb * size;
+
+ /*
+ * Don't bother too much if we're shrinking just a bit,
+ * we do not shrink for series of small steps, oh well.
+ */
+ if (newsize <= oldsize) {
+ size_t d = oldsize - newsize;
+
+ if (d < oldsize / 2 && d < (size_t)getpagesize()) {
+ memset((char *)ptr + newsize, 0, d);
+ return ptr;
+ }
+ }
+
+ newptr = malloc(newsize);
+ if (newptr == NULL)
+ return NULL;
+
+ if (newsize > oldsize) {
+ memcpy(newptr, ptr, oldsize);
+ memset((char *)newptr + oldsize, 0, newsize - oldsize);
+ } else
+ memcpy(newptr, ptr, newsize);
+
+ explicit_bzero(ptr, oldsize);
+ free(ptr);
+
+ return newptr;
+}
commit 9c85d828a1abdd698f8a587abe8cbbaaa80eade8
Author: Seth R Johnson <johnsonsr at ornl.gov>
Date: Thu Nov 14 07:26:41 2019 -0500
Fix ELF detection on Intel compilers
The Intel compiler does not define __amd64__ on x86_64 platforms;
instead, like other compilers, it defines __x86_64__ .
Closes: !8
Signed-off-by: Guillem Jover <guillem at hadrons.org>
diff --git a/src/local-elf.h b/src/local-elf.h
index f784b12..98a2962 100644
--- a/src/local-elf.h
+++ b/src/local-elf.h
@@ -45,7 +45,7 @@
#define ELF_TARG_CLASS ELFCLASS64
#define ELF_TARG_DATA ELFDATA2LSB
-#elif defined(__amd64__)
+#elif defined(__amd64__) || defined(__x86_64__)
#define ELF_TARG_MACH EM_X86_64
#if defined(__ILP32__)
More information about the libbsd
mailing list