Introducing: void *mallocarray(size_t nmemb, size_t size);
authorderaadt <deraadt@openbsd.org>
Mon, 21 Apr 2014 13:17:32 +0000 (13:17 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 21 Apr 2014 13:17:32 +0000 (13:17 +0000)
Like calloc(), except without the cleared-memory gaurantee
ok beck guenther, discussed for more than a year...

include/stdlib.h
lib/libc/stdlib/Makefile.inc
lib/libc/stdlib/malloc.3
lib/libc/stdlib/malloc.c

index a2310e3..93eddce 100644 (file)
@@ -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);
index 953c533..ec43b63 100644 (file)
@@ -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
index 414f0a9..2a636b8 100644 (file)
 .\" 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
 .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 .
index 2cd4431..b48dcb3 100644 (file)
@@ -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 <otto@drijf.net>
  * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -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)
 {