diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2018-05-06 12:24:45 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2018-05-06 12:24:45 +0000 |
| commit | 20adc8f2a99cd37b64a80ef63dfc5ba6627d4dfb (patch) | |
| tree | ad57ce9ac9538c780c802adbdfc4c581f9100310 /openbsd-compat | |
| parent | 343d57711556d429eda777ab259ff924acbd6b34 (diff) | |
Diffstat (limited to 'openbsd-compat')
| -rw-r--r-- | openbsd-compat/Makefile.in | 4 | ||||
| -rw-r--r-- | openbsd-compat/bsd-err.c | 6 | ||||
| -rw-r--r-- | openbsd-compat/bsd-getpagesize.c | 23 | ||||
| -rw-r--r-- | openbsd-compat/bsd-malloc.c | 55 | ||||
| -rw-r--r-- | openbsd-compat/bsd-misc.c | 10 | ||||
| -rw-r--r-- | openbsd-compat/bsd-misc.h | 4 | ||||
| -rw-r--r-- | openbsd-compat/explicit_bzero.c | 4 | ||||
| -rw-r--r-- | openbsd-compat/fmt_scaled.c | 18 | ||||
| -rw-r--r-- | openbsd-compat/freezero.c | 29 | ||||
| -rw-r--r-- | openbsd-compat/openbsd-compat.h | 12 | ||||
| -rw-r--r-- | openbsd-compat/port-tun.c | 93 | ||||
| -rw-r--r-- | openbsd-compat/port-tun.h | 5 | ||||
| -rw-r--r-- | openbsd-compat/recallocarray.c | 90 |
13 files changed, 297 insertions, 56 deletions
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index d51eacf6562a3..ac8ae4305d0bc 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -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 freezero.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-malloc.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-err.c b/openbsd-compat/bsd-err.c index ab10646f023ad..e4ed22b86a259 100644 --- a/openbsd-compat/bsd-err.c +++ b/openbsd-compat/bsd-err.c @@ -27,6 +27,12 @@ #include "includes.h" +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + #ifndef HAVE_ERR void err(int r, const char *fmt, ...) diff --git a/openbsd-compat/bsd-getpagesize.c b/openbsd-compat/bsd-getpagesize.c new file mode 100644 index 0000000000000..9daddfbd38655 --- /dev/null +++ b/openbsd-compat/bsd-getpagesize.c @@ -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 */ diff --git a/openbsd-compat/bsd-malloc.c b/openbsd-compat/bsd-malloc.c new file mode 100644 index 0000000000000..6402ab588b095 --- /dev/null +++ b/openbsd-compat/bsd-malloc.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017 Darren Tucker (dtucker at zip com au). + * + * 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 "config.h" +#undef malloc +#undef calloc +#undef realloc + +#include <sys/types.h> +#include <stdlib.h> + +#if defined(HAVE_MALLOC) && HAVE_MALLOC == 0 +void * +rpl_malloc(size_t size) +{ + if (size == 0) + size = 1; + return malloc(size); +} +#endif + +#if defined(HAVE_CALLOC) && HAVE_CALLOC == 0 +void * +rpl_calloc(size_t nmemb, size_t size) +{ + if (nmemb == 0) + nmemb = 1; + if (size == 0) + size = 1; + return calloc(nmemb, size); +} +#endif + +#if defined (HAVE_REALLOC) && HAVE_REALLOC == 0 +void * +rpl_realloc(void *ptr, size_t size) +{ + if (size == 0) + size = 1; + return realloc(ptr, size); +} +#endif diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index cfd73260ae187..29f6ad38c5a1a 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -104,6 +104,16 @@ const char *strerror(int e) } #endif +#if !defined(HAVE_STRSIGNAL) +char *strsignal(int sig) +{ + static char buf[16]; + + (void)snprintf(buf, sizeof(buf), "%d", sig); + return buf; +} +#endif + #ifndef HAVE_UTIMES int utimes(char *filename, struct timeval *tvp) { diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index 70a538f04e2d6..0b1a3504f2cc6 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -49,6 +49,10 @@ int setegid(uid_t); const char *strerror(int); #endif +#if !defined(HAVE_STRSIGNAL) +char *strsignal(int); +#endif + #if !defined(HAVE_SETLINEBUF) #define setlinebuf(a) (setvbuf((a), NULL, _IOLBF, 0)) #endif diff --git a/openbsd-compat/explicit_bzero.c b/openbsd-compat/explicit_bzero.c index 5078134d137a8..53a003472721d 100644 --- a/openbsd-compat/explicit_bzero.c +++ b/openbsd-compat/explicit_bzero.c @@ -20,6 +20,8 @@ void explicit_bzero(void *p, size_t n) { + if (n == 0) + return; (void)memset_s(p, n, 0, n); } @@ -34,6 +36,8 @@ static void (* volatile ssh_bzero)(void *, size_t) = bzero; void explicit_bzero(void *p, size_t n) { + if (n == 0) + return; /* * clang -fsanitize=memory needs to intercept memset-like functions * to correctly detect memory initialisation. Make sure one is called diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c index e5533b2de90ce..7c5193e26d959 100644 --- a/openbsd-compat/fmt_scaled.c +++ b/openbsd-compat/fmt_scaled.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fmt_scaled.c,v 1.13 2017/03/11 23:37:23 djm Exp $ */ +/* $OpenBSD: fmt_scaled.c,v 1.16 2017/03/16 02:40:46 dtucker Exp $ */ /* * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved. @@ -125,22 +125,30 @@ scan_scaled(char *scaled, long long *result) /* ignore extra fractional digits */ continue; fract_digits++; /* for later scaling */ - if (fpart >= LLONG_MAX / 10) { + if (fpart > LLONG_MAX / 10) { errno = ERANGE; return -1; } fpart *= 10; + if (i > LLONG_MAX - fpart) { + errno = ERANGE; + return -1; + } fpart += i; } else { /* normal digit */ if (++ndigits >= MAX_DIGITS) { errno = ERANGE; return -1; } - if (whole >= LLONG_MAX / 10) { + if (whole > LLONG_MAX / 10) { errno = ERANGE; return -1; } whole *= 10; + if (i > LLONG_MAX - whole) { + errno = ERANGE; + return -1; + } whole += i; } } @@ -170,7 +178,9 @@ scan_scaled(char *scaled, long long *result) } scale_fact = scale_factors[i]; - if (whole >= LLONG_MAX / scale_fact) { + /* check for overflow and underflow after scaling */ + if (whole > LLONG_MAX / scale_fact || + whole < LLONG_MIN / scale_fact) { errno = ERANGE; return -1; } diff --git a/openbsd-compat/freezero.c b/openbsd-compat/freezero.c new file mode 100644 index 0000000000000..3af8f4a733e96 --- /dev/null +++ b/openbsd-compat/freezero.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008, 2010, 2011, 2016 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 "includes.h" + +#ifndef HAVE_FREEZERO + +void +freezero(void *ptr, size_t sz) +{ + explicit_bzero(ptr, sz); + free(ptr); +} + +#endif /* HAVE_FREEZERO */ + diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index cff547745b885..cac799e8446ff 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -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 @@ -296,6 +304,10 @@ int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t, void explicit_bzero(void *p, size_t n); #endif +#ifndef HAVE_FREEZERO +void freezero(void *, size_t); +#endif + char *xcrypt(const char *password, const char *salt); char *shadow_pw(struct passwd *pw); diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c index a444adf1d5934..7579c6084a1f8 100644 --- a/openbsd-compat/port-tun.c +++ b/openbsd-compat/port-tun.c @@ -199,84 +199,81 @@ sys_tun_open(int tun, int mode) */ #if defined(SSH_TUN_FILTER) +/* + * The tunnel forwarding protocol prepends the address family of forwarded + * IP packets using OpenBSD's numbers. + */ #define OPENBSD_AF_INET 2 #define OPENBSD_AF_INET6 24 int -sys_tun_infilter(struct Channel *c, char *buf, int len) +sys_tun_infilter(struct ssh *ssh, struct Channel *c, char *buf, int _len) { + int r; + size_t len; + char *ptr = buf; #if defined(SSH_TUN_PREPEND_AF) char rbuf[CHAN_RBUF]; - struct ip *iph; + struct ip iph; #endif - u_int32_t *af; - char *ptr = buf; - int r; - -#if defined(SSH_TUN_PREPEND_AF) - if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af))) - return (-1); - ptr = (char *)&rbuf[0]; - bcopy(buf, ptr + sizeof(u_int32_t), len); - len += sizeof(u_int32_t); - af = (u_int32_t *)ptr; - - iph = (struct ip *)(ptr + sizeof(u_int32_t)); - switch (iph->ip_v) { - case 6: - *af = AF_INET6; - break; - case 4: - default: - *af = AF_INET; - break; - } +#if defined(SSH_TUN_PREPEND_AF) || defined(SSH_TUN_COMPAT_AF) + u_int32_t af; #endif -#if defined(SSH_TUN_COMPAT_AF) - if (len < (int)sizeof(u_int32_t)) - return (-1); + /* XXX update channel input filter API to use unsigned length */ + if (_len < 0) + return -1; + len = _len; - af = (u_int32_t *)ptr; - if (*af == htonl(AF_INET6)) - *af = htonl(OPENBSD_AF_INET6); - else - *af = htonl(OPENBSD_AF_INET); +#if defined(SSH_TUN_PREPEND_AF) + if (len <= sizeof(iph) || len > sizeof(rbuf) - 4) + return -1; + /* Determine address family from packet IP header. */ + memcpy(&iph, buf, sizeof(iph)); + af = iph.ip_v == 6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET; + /* Prepend address family to packet using OpenBSD constants */ + memcpy(rbuf + 4, buf, len); + len += 4; + POKE_U32(rbuf, af); + ptr = rbuf; +#elif defined(SSH_TUN_COMPAT_AF) + /* Convert existing address family header to OpenBSD value */ + if (len <= 4) + return -1; + af = PEEK_U32(buf); + /* Put it back */ + POKE_U32(buf, af == AF_INET6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET); #endif - if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0) + if ((r = sshbuf_put_string(c->input, ptr, len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); return (0); } u_char * -sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) +sys_tun_outfilter(struct ssh *ssh, struct Channel *c, + u_char **data, size_t *dlen) { u_char *buf; - u_int32_t *af; + u_int32_t af; int r; - size_t xxx_dlen; /* XXX new API is incompatible with this signature. */ - if ((r = sshbuf_get_string(&c->output, data, &xxx_dlen)) != 0) + if ((r = sshbuf_get_string(c->output, data, dlen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (dlen != NULL) - *dlen = xxx_dlen; - if (*dlen < sizeof(*af)) + if (*dlen < sizeof(af)) return (NULL); buf = *data; #if defined(SSH_TUN_PREPEND_AF) - *dlen -= sizeof(u_int32_t); - buf = *data + sizeof(u_int32_t); + /* skip address family */ + *dlen -= sizeof(af); + buf = *data + sizeof(af); #elif defined(SSH_TUN_COMPAT_AF) - af = ntohl(*(u_int32_t *)buf); - if (*af == OPENBSD_AF_INET6) - *af = htonl(AF_INET6); - else - *af = htonl(AF_INET); + /* translate address family */ + af = (PEEK_U32(buf) == OPENBSD_AF_INET6) ? AF_INET6 : AF_INET; + POKE_U32(buf, af); #endif - return (buf); } #endif /* SSH_TUN_FILTER */ diff --git a/openbsd-compat/port-tun.h b/openbsd-compat/port-tun.h index c53df01fceb60..103514370fd39 100644 --- a/openbsd-compat/port-tun.h +++ b/openbsd-compat/port-tun.h @@ -18,6 +18,7 @@ #define _PORT_TUN_H struct Channel; +struct ssh; #if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) # define CUSTOM_SYS_TUN_OPEN @@ -26,8 +27,8 @@ int sys_tun_open(int, int); #if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) # define SSH_TUN_FILTER -int sys_tun_infilter(struct Channel *, char *, int); -u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *); +int sys_tun_infilter(struct ssh *, struct Channel *, char *, int); +u_char *sys_tun_outfilter(struct ssh *, struct Channel *, u_char **, size_t *); #endif #endif diff --git a/openbsd-compat/recallocarray.c b/openbsd-compat/recallocarray.c new file mode 100644 index 0000000000000..3e1156ce2d959 --- /dev/null +++ b/openbsd-compat/recallocarray.c @@ -0,0 +1,90 @@ +/* $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> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#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; +} +/* DEF_WEAK(recallocarray); */ + +#endif /* HAVE_RECALLOCARRAY */ |
