diff options
author | Yuri Pankov <yuri.pankov@nexenta.com> | 2017-07-28 14:44:18 +0300 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2017-07-29 22:55:08 +0000 |
commit | f1cdbd3731f01314c1d46f05280ad63f1770fdc6 (patch) | |
tree | c5a25b595ef96005afa9734a6347a7e910c5b9b2 | |
parent | 0b905b49d460a57773d88d714cd880ffe0182b7c (diff) | |
download | illumos-joyent-f1cdbd3731f01314c1d46f05280ad63f1770fdc6.tar.gz |
8546 want recallocarray(3C) and freezero(3C)
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: Andy Stormont <astormont@racktopsystems.com>
Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r-- | usr/src/head/stdlib.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libc/amd64/Makefile | 2 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/Makefile.com | 2 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/freezero.c | 27 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/reallocarray.c | 8 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/recallocarray.c | 80 | ||||
-rw-r--r-- | usr/src/lib/libc/port/llib-lc | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 13 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/Makefile.com | 2 | ||||
-rw-r--r-- | usr/src/lib/libc/sparcv9/Makefile.com | 2 | ||||
-rw-r--r-- | usr/src/man/man3c/Makefile | 4 | ||||
-rw-r--r-- | usr/src/man/man3c/malloc.3c | 108 | ||||
-rw-r--r-- | usr/src/pkg/manifests/system-library.man3c.inc | 2 |
13 files changed, 239 insertions, 19 deletions
diff --git a/usr/src/head/stdlib.h b/usr/src/head/stdlib.h index 6e38ce5d70..8583aa51bd 100644 --- a/usr/src/head/stdlib.h +++ b/usr/src/head/stdlib.h @@ -290,7 +290,9 @@ extern char *ulltostr(unsigned long long, char *); extern uint32_t arc4random(void); extern void arc4random_buf(void *, size_t); extern uint32_t arc4random_uniform(uint32_t); +extern void freezero(void *, size_t); extern void *reallocarray(void *, size_t, size_t); +extern void *recallocarray(void *, size_t, size_t, size_t); extern long long strtonum(const char *, long long, long long, const char **); #endif /* !_STRICT_SYBMOLS */ diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index 8cee9dee02..2fe0b7bafe 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -395,6 +395,7 @@ PORTGEN= \ flock.o \ fls.o \ fmtmsg.o \ + freezero.o \ ftime.o \ ftok.o \ fts.o \ @@ -513,6 +514,7 @@ PORTGEN= \ readdir.o \ readdir_r.o \ reallocarray.o \ + recallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 0a879e1508..3edbed15e0 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -431,6 +431,7 @@ PORTGEN= \ flock.o \ fls.o \ fmtmsg.o \ + freezero.o \ ftime.o \ ftok.o \ fts.o \ @@ -549,6 +550,7 @@ PORTGEN= \ readdir.o \ readdir_r.o \ reallocarray.o \ + recallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ diff --git a/usr/src/lib/libc/port/gen/freezero.c b/usr/src/lib/libc/port/gen/freezero.c new file mode 100644 index 0000000000..9280590aa6 --- /dev/null +++ b/usr/src/lib/libc/port/gen/freezero.c @@ -0,0 +1,27 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2017 Nexenta Systems, Inc. + */ + +#include <stdlib.h> +#include <strings.h> + +void +freezero(void *ptr, size_t size) +{ + if (ptr == NULL) + return; + + explicit_bzero(ptr, size); + free(ptr); +} diff --git a/usr/src/lib/libc/port/gen/reallocarray.c b/usr/src/lib/libc/port/gen/reallocarray.c index ecc4d25fa9..ba1f028c42 100644 --- a/usr/src/lib/libc/port/gen/reallocarray.c +++ b/usr/src/lib/libc/port/gen/reallocarray.c @@ -26,12 +26,12 @@ #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof (size_t) * 4)) void * -reallocarray(void *optr, size_t nmemb, size_t size) +reallocarray(void *ptr, size_t nelem, size_t elsize) { - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { + if ((nelem >= MUL_NO_OVERFLOW || elsize >= MUL_NO_OVERFLOW) && + nelem > 0 && SIZE_MAX / nelem < elsize) { errno = ENOMEM; return (NULL); } - return (realloc(optr, size * nmemb)); + return (realloc(ptr, elsize * nelem)); } diff --git a/usr/src/lib/libc/port/gen/recallocarray.c b/usr/src/lib/libc/port/gen/recallocarray.c new file mode 100644 index 0000000000..1edcbef960 --- /dev/null +++ b/usr/src/lib/libc/port/gen/recallocarray.c @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#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 oldnelem, size_t newnelem, size_t elsize) +{ + size_t oldsize, newsize; + void *newptr; + + if (ptr == NULL) + return (calloc(newnelem, elsize)); + + if ((newnelem >= MUL_NO_OVERFLOW || elsize >= MUL_NO_OVERFLOW) && + newnelem > 0 && SIZE_MAX / newnelem < elsize) { + errno = ENOMEM; + return (NULL); + } + newsize = newnelem * elsize; + + if ((oldnelem >= MUL_NO_OVERFLOW || elsize >= MUL_NO_OVERFLOW) && + oldnelem > 0 && SIZE_MAX / oldnelem < elsize) { + errno = EINVAL; + return (NULL); + } + oldsize = oldnelem * elsize; + + /* + * 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()) { + (void) memset((char *)ptr + newsize, 0, d); + return (ptr); + } + } + + newptr = malloc(newsize); + if (newptr == NULL) + return (NULL); + + if (newsize > oldsize) { + (void) memcpy(newptr, ptr, oldsize); + (void) memset((char *)newptr + oldsize, 0, newsize - oldsize); + } else { + (void) memcpy(newptr, ptr, newsize); + } + + explicit_bzero(ptr, oldsize); + free(ptr); + + return (newptr); +} diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc index db73a140f9..f547dd44da 100644 --- a/usr/src/lib/libc/port/llib-lc +++ b/usr/src/lib/libc/port/llib-lc @@ -438,6 +438,9 @@ int addseverity(int value, const char *string); int fmtmsg(long class, const char *label, int severity, const char *text, const char *action, const char *tag); +/* freezero.c */ +void freezero(void *, size_t); + /* ftime.c */ int ftime(struct timeb *tp); @@ -831,6 +834,9 @@ struct dirent *readdir(DIR *dirp); /* reallocarray.c */ void *reallocarray(void *, size_t, size_t); +/* recallocarray.c */ +void *recallocarray(void *, size_t, size_t, size_t); + /* realpath.c */ char *realpath(const char *_RESTRICT_KYWD raw, char *_RESTRICT_KYWD canon); diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index c9e03580e2..905de27667 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -18,17 +18,16 @@ # # CDDL HEADER END # + # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# -# Copyright 2010 Nexenta Systems, Inc. All rights reserved. -# Use is subject to license terms. -# +# Copyright 2017 Nexenta Systems, Inc. # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2016 Joyent, Inc. # Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright (c) 2013 Gary Mills # Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # # MAPFILE HEADER START @@ -93,6 +92,12 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.24 { # openbsd compat + protected: + freezero; + recallocarray; +} ILLUMOS_0.23; + SYMBOL_VERSION ILLUMOS_0.23 { # openbsd compat protected: fts_children; diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index b478c61a74..8ad448f56a 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -456,6 +456,7 @@ PORTGEN= \ flock.o \ fls.o \ fmtmsg.o \ + freezero.o \ ftime.o \ ftok.o \ fts.o \ @@ -575,6 +576,7 @@ PORTGEN= \ readdir.o \ readdir_r.o \ reallocarray.o \ + recallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index 70d1fdea43..5c131719c9 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -414,6 +414,7 @@ PORTGEN= \ flock.o \ fls.o \ fmtmsg.o \ + freezero.o \ ftime.o \ ftok.o \ fts.o \ @@ -533,6 +534,7 @@ PORTGEN= \ readdir.o \ readdir_r.o \ reallocarray.o \ + recallocarray.o \ realpath.o \ reboot.o \ regexpr.o \ diff --git a/usr/src/man/man3c/Makefile b/usr/src/man/man3c/Makefile index 0d8c89c217..47443e6fd8 100644 --- a/usr/src/man/man3c/Makefile +++ b/usr/src/man/man3c/Makefile @@ -814,6 +814,7 @@ MANLINKS= FD_CLR.3c \ fputs.3c \ free.3c \ freelocale.3c \ + freezero.3c \ fscanf.3c \ fseeko.3c \ fsetattr.3c \ @@ -1138,6 +1139,7 @@ MANLINKS= FD_CLR.3c \ readdir_r.3c \ realloc.3c \ reallocarray.3c \ + recallocarray.3c \ regerror.3c \ regex.3c \ regexec.3c \ @@ -1937,9 +1939,11 @@ minor.3c := LINKSRC = makedev.3c alloca.3c := LINKSRC = malloc.3c calloc.3c := LINKSRC = malloc.3c free.3c := LINKSRC = malloc.3c +freezero.3c := LINKSRC = malloc.3c memalign.3c := LINKSRC = malloc.3c realloc.3c := LINKSRC = malloc.3c reallocarray.3c := LINKSRC = malloc.3c +recallocarray.3c := LINKSRC = malloc.3c valloc.3c := LINKSRC = malloc.3c mblen_l.3c := LINKSRC = mblen.3c diff --git a/usr/src/man/man3c/malloc.3c b/usr/src/man/man3c/malloc.3c index f0c69f02f5..79b7a6f4fa 100644 --- a/usr/src/man/man3c/malloc.3c +++ b/usr/src/man/man3c/malloc.3c @@ -17,17 +17,20 @@ .\" .\" Copyright 1989 AT&T .\" Copyright (c) 2005, Sun Microsystems, Inc. All Rights Reserved. +.\" Copyright 2017 Nexenta Systems, Inc. .\" -.Dd March 10, 2017 +.Dd July 28, 2017 .Dt MALLOC 3C .Os .Sh NAME .Nm malloc , .Nm calloc , .Nm free , +.Nm freezero , .Nm memalign , .Nm realloc , .Nm reallocarray , +.Nm recallocarray , .Nm valloc , .Nm alloca .Nd memory allocator @@ -46,6 +49,11 @@ .Fo free .Fa "void *ptr" .Fc +.Ft void +.Fo freezero +.Fa "void *ptr" +.Fa "size_t size" +.Fc .Ft void * .Fo memalign .Fa "size_t alignment" @@ -63,6 +71,13 @@ .Fa "size_t elsize" .Fc .Ft void * +.Fo recallocarray +.Fa "void *ptr" +.Fa "size_t oldnelem" +.Fa "size_t newnelem" +.Fa "size_t elsize" +.Fc +.Ft void * .Fo valloc .Fa "size_t size" .Fc @@ -92,8 +107,9 @@ is a pointer to a block previously allocated by .Fn malloc , .Fn calloc , .Fn realloc , +.Fn reallocarray , or -.Fn reallocarray . +.Fn recallocarray . After .Fn free is executed, this space is made available for further allocation by the @@ -107,6 +123,32 @@ If a random number is passed to the results are undefined. .Pp 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 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. +.Pp +The .Fn calloc function allocates space for an array of .Fa nelem @@ -167,6 +209,30 @@ and checks for overflow in calculation. .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 oldnelem +is ignored and the call is equivalent to +.Fn calloc . +If +.Fa ptr +is not +.Dv NULL , +.Fa oldnelem +must be a value such that +.Fa oldnelem Ns * Ns Fa elsize +is the size of the earlier allocation that returned +.Fa ptr , +otherwise the behaviour is undefined. +.Pp +The .Fn valloc function has the same effect as .Fn malloc , @@ -191,18 +257,17 @@ for storage of any type of object. .Pp If there is no available memory, .Fn malloc , +.Fn calloc , .Fn realloc , .Fn reallocarray , +.Fn recallocarray , .Fn memalign , -.Fn valloc , and -.Fn calloc +.Fn valloc return a null pointer. .Pp When .Fn realloc -or -.Fn reallocarray is called with .Fa size > 0 and returns @@ -223,14 +288,17 @@ If .Fn malloc , .Fn calloc , .Fn realloc , +.Fn reallocarray , or -.Fn reallocarray +.Fn recallocarray returns unsuccessfully, .Va errno will be set to indicate the error. The .Fn free -function does not set +and +.Fn freezero +functions do not set .Va errno . .Sh ERRORS The @@ -240,7 +308,7 @@ The and .Fn reallocarray functions will fail if: -.Bl -tag -width "ENOMEM" +.Bl -tag -width Er .It Er ENOMEM The physical limits of the system are exceeded by .Fa size @@ -251,6 +319,21 @@ There is not enough memory available to allocate .Fa size bytes of memory; but the application could try again later. .El +.Pp +The +.Fn recallocarray +function will fail if: +.Bl -tag -width Er +.It Er EINVAL +.Fa ptr +is not +.Dv NULL +and multiplying +.Fa oldnelem +and +.Fa elsize +results in integer overflow. +.El .Sh USAGE Portable applications should avoid using .Fn valloc @@ -298,8 +381,11 @@ functions are .Sy Standard. .Pp The -.Fn reallocarray -function is +.Fn freezero , +.Fn reallocarray , +and +.Fn recallocarray +functions are .Sy Committed . .Pp The diff --git a/usr/src/pkg/manifests/system-library.man3c.inc b/usr/src/pkg/manifests/system-library.man3c.inc index 0a07bd5222..ce84471c6a 100644 --- a/usr/src/pkg/manifests/system-library.man3c.inc +++ b/usr/src/pkg/manifests/system-library.man3c.inc @@ -814,6 +814,7 @@ link path=usr/share/man/man3c/fpsetsticky.3c target=fpgetround.3c link path=usr/share/man/man3c/fputs.3c target=puts.3c link path=usr/share/man/man3c/free.3c target=malloc.3c link path=usr/share/man/man3c/freelocale.3c target=newlocale.3c +link path=usr/share/man/man3c/freezero.3c target=malloc.3c link path=usr/share/man/man3c/fscanf.3c target=scanf.3c link path=usr/share/man/man3c/fseeko.3c target=fseek.3c link path=usr/share/man/man3c/fsetattr.3c target=fgetattr.3c @@ -1205,6 +1206,7 @@ link path=usr/share/man/man3c/re_exec.3c target=re_comp.3c link path=usr/share/man/man3c/readdir_r.3c target=readdir.3c link path=usr/share/man/man3c/realloc.3c target=malloc.3c link path=usr/share/man/man3c/reallocarray.3c target=malloc.3c +link path=usr/share/man/man3c/recallocarray.3c target=malloc.3c link path=usr/share/man/man3c/regerror.3c target=regcomp.3c link path=usr/share/man/man3c/regex.3c target=regcmp.3c link path=usr/share/man/man3c/regexec.3c target=regcomp.3c |