]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
add recallocarray replacement and dependency
authorDamien Miller <djm@mindrot.org>
Thu, 1 Jun 2017 05:25:13 +0000 (15:25 +1000)
committerDamien Miller <djm@mindrot.org>
Thu, 1 Jun 2017 05:25:13 +0000 (15:25 +1000)
recallocarray() needs getpagesize() so add a tiny replacement for that.

configure.ac
openbsd-compat/Makefile.in
openbsd-compat/bsd-getpagesize.c [new file with mode: 0644]
openbsd-compat/openbsd-compat.h
openbsd-compat/recallocarray.c [new file with mode: 0644]

index 895c5211ea93c292345ab0ee881044107cd1a607..46f7d49572923045bcc39d3f41f9fa6634b9e723 100644 (file)
@@ -1678,6 +1678,7 @@ AC_CHECK_FUNCS([ \
        getgrouplist \
        getnameinfo \
        getopt \
+       getpagesize \
        getpeereid \
        getpeerucred \
        getpgid \
@@ -1708,6 +1709,7 @@ AC_CHECK_FUNCS([ \
        readpassphrase \
        reallocarray \
        recvmsg \
+       recallocarray \
        rresvport_af \
        sendmsg \
        setdtablesize \
index d51eacf6562a340c6341704a6fa3ebc419f35f74..b5088c479bbb198b0ac188852040b6e08d3d88ea 100644 (file)
@@ -16,9 +16,9 @@ RANLIB=@RANLIB@
 INSTALL=@INSTALL@
 LDFLAGS=-L. @LDFLAGS@
 
-OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
+OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o recallocarray.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
 
-COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
+COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
 
 PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
 
diff --git a/openbsd-compat/bsd-getpagesize.c b/openbsd-compat/bsd-getpagesize.c
new file mode 100644 (file)
index 0000000..9daddfb
--- /dev/null
@@ -0,0 +1,23 @@
+/* Placed in the public domain */
+
+#ifndef HAVE_GETPAGESIZE
+
+#include <unistd.h>
+#include <limits.h>
+
+int
+getpagesize(void)
+{
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+       long r = sysconf(_SC_PAGESIZE);
+       if (r > 0 && r < INT_MAX)
+               return (int)r;
+#endif
+       /*
+        * This is at the lower end of common values and appropriate for
+        * our current use of getpagesize() in recallocarray().
+        */
+       return 4096;
+}
+
+#endif /* HAVE_GETPAGESIZE */
index cff547745b885dd93043908d783eb6976526076b..a741bc23e917cb99741353d62ba1226d2dcba749 100644 (file)
@@ -60,6 +60,10 @@ int bindresvport_sa(int sd, struct sockaddr *sa);
 void closefrom(int);
 #endif
 
+#ifndef HAVE_GETPAGESIZE
+int getpagesize(void);
+#endif
+
 #ifndef HAVE_GETCWD
 char *getcwd(char *pt, size_t size);
 #endif
@@ -68,6 +72,10 @@ char *getcwd(char *pt, size_t size);
 void *reallocarray(void *, size_t, size_t);
 #endif
 
+#ifndef HAVE_RECALLOCARRAY
+void *recallocarray(void *, size_t, size_t, size_t);
+#endif
+
 #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
 /*
  * glibc's FORTIFY_SOURCE can redefine this and prevent us picking up the
diff --git a/openbsd-compat/recallocarray.c b/openbsd-compat/recallocarray.c
new file mode 100644 (file)
index 0000000..5067417
--- /dev/null
@@ -0,0 +1,88 @@
+/*     $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $  */
+/*
+ * Copyright (c) 2008, 2017 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.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */
+
+#include "includes.h"
+#ifndef HAVE_RECALLOCARRAY
+
+#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 < 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;
+}
+/* DEF_WEAK(recallocarray); */
+
+#endif /* HAVE_RECALLOCARRAY */