diff options
| author | christos <christos@NetBSD.org> | 2019-03-08 20:34:24 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2019-03-08 20:34:24 +0000 |
| commit | c58bb9e093aaf0f6fd2a89d59280fb46741bc562 (patch) | |
| tree | b08a4cc6f3f31995a7182705f450e52e3098c92b /crypto | |
| parent | 6d8bf4dc44051f96b0ffb26c801157150e61004b (diff) | |
Replace our buggy recallocarray implementation one with the portable one
from OpenBSD.
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/external/bsd/openssh/dist/recallocarray.c | 112 |
1 files changed, 76 insertions, 36 deletions
diff --git a/crypto/external/bsd/openssh/dist/recallocarray.c b/crypto/external/bsd/openssh/dist/recallocarray.c index eed1973339b..29205da6923 100644 --- a/crypto/external/bsd/openssh/dist/recallocarray.c +++ b/crypto/external/bsd/openssh/dist/recallocarray.c @@ -1,51 +1,91 @@ -/* $NetBSD: recallocarray.c,v 1.1 2017/10/07 21:14:59 christos Exp $ */ -/* $OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $ */ +/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */ -/*- - * Copyright (c) 2015 The NetBSD Foundation, Inc. - * All rights reserved. +/* + * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net> * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. + * 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. * - * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * 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" -#include <sys/cdefs.h> -__RCSID("$NetBSD: recallocarray.c,v 1.1 2017/10/07 21:14:59 christos Exp $"); +#ifndef HAVE_RECALLOCARRAY #include <errno.h> -#include <string.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 *optr, size_t omemb, size_t nmemb, size_t size) +recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) { - char *nptr = reallocarray(optr, nmemb, size); + size_t oldsize, newsize; + void *newptr; + + if (ptr == NULL) + return calloc(newnmemb, size); - if (nptr == NULL || omemb >= nmemb) - return nptr; + if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + newnmemb > 0 && SIZE_MAX / newnmemb < size) { + errno = ENOMEM; + return NULL; + } + newsize = newnmemb * size; - memset(nptr + omemb * size, 0, (nmemb - omemb) * size); - return nptr; + 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 */ |
