diff --git a/src/include/stdlib.h b/src/include/stdlib.h index a2310e36..93eddce7 100644 --- a/src/include/stdlib.h +++ b/src/include/stdlib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stdlib.h,v 1.56 2013/12/28 01:51:53 martynas Exp $ */ +/* $OpenBSD: stdlib.h,v 1.57 2014/04/21 13:17:32 deraadt Exp $ */ /* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */ /*- @@ -124,6 +124,9 @@ char *getenv(const char *); long labs(long); ldiv_t ldiv(long, long); void *malloc(size_t); +#if __BSD_VISIBLE +void *mallocarray(size_t, size_t); +#endif /* __BSD_VISIBLE */ void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); int rand(void); void *realloc(void *, size_t); diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc index 953c5338..ec43b631 100644 --- a/src/lib/libc/stdlib/Makefile.inc +++ b/src/lib/libc/stdlib/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.49 2014/03/18 22:36:29 miod Exp $ +# $OpenBSD: Makefile.inc,v 1.50 2014/04/21 13:17:32 deraadt Exp $ # stdlib sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib @@ -44,7 +44,7 @@ MLINKS+=insque.3 remque.3 MLINKS+=labs.3 llabs.3 MLINKS+=lsearch.3 lfind.3 MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3 -MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5 +MLINKS+=malloc.3 mallocarray.5 malloc.3 cfree.3 malloc.3 malloc.conf.5 MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 MLINKS+=radixsort.3 sradixsort.3 MLINKS+=rand.3 srand.3 rand.3 rand_r.3 diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 index 414f0a97..2a636b88 100644 --- a/src/lib/libc/stdlib/malloc.3 +++ b/src/lib/libc/stdlib/malloc.3 @@ -30,14 +30,15 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: malloc.3,v 1.73 2013/07/18 10:14:49 schwarze Exp $ +.\" $OpenBSD: malloc.3,v 1.74 2014/04/21 13:17:32 deraadt Exp $ .\" -.Dd $Mdocdate: July 18 2013 $ +.Dd $Mdocdate: April 21 2014 $ .Dt MALLOC 3 .Os .Sh NAME .Nm malloc , .Nm calloc , +.Nm mallocarray , .Nm realloc , .Nm free , .Nm cfree @@ -49,12 +50,14 @@ .Ft void * .Fn calloc "size_t nmemb" "size_t size" .Ft void * +.Fn mallocarray "size_t nmemb" "size_t size" +.Ft void * .Fn realloc "void *ptr" "size_t size" .Ft void .Fn free "void *ptr" .Ft void .Fn cfree "void *ptr" -.Ft char * +.Ft char * Ns .Va malloc_options ; .Sh DESCRIPTION The @@ -91,10 +94,18 @@ if ((p = malloc(num * size)) == NULL) err(1, "malloc"); .Ed .Pp -The multiplication may lead to an integer overflow. -To avoid this, +The multiplication may lead to an integer overflow, which can +be avoided using the extension +.Fn mallocarray , +as follows: +.Bd -literal -offset indent +if ((p = mallocarray(num, size)) == NULL) + err(1, "malloc"); +.Ed +.Pp +Alternatively .Fn calloc -is recommended. +is a more portable solution which comes with the cost of clearing memory. .Pp If .Fn malloc @@ -324,7 +335,8 @@ it is buggy. The default number of free pages cached is 64. .Sh RETURN VALUES The -.Fn malloc +.Fn malloc , +.Fn mallocarray , and .Fn calloc functions return a pointer to the allocated space if successful; otherwise, @@ -482,3 +494,6 @@ random. A rewrite by Otto Moerbeek introducing a new central data structure and more randomization appeared in .Ox 4.4 . +.Fn mallocarray +appeared in +.Ox 5.6 . diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 2cd44319..b48dcb39 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: malloc.c,v 1.153 2014/04/14 10:29:41 otto Exp $ */ +/* $OpenBSD: malloc.c,v 1.154 2014/04/21 13:17:32 deraadt Exp $ */ /* * Copyright (c) 2008, 2010, 2011 Otto Moerbeek * Copyright (c) 2012 Matthew Dempsky @@ -1432,6 +1432,17 @@ calloc(size_t nmemb, size_t size) return r; } +void * +mallocarray(size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return malloc(size * nmemb); +} + static void * mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill) {