summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2018-01-10 21:49:45 +0000
committerConrad Meyer <cem@FreeBSD.org>2018-01-10 21:49:45 +0000
commitc02fc9607a219ec673b148cdfc211b15ce687b80 (patch)
treecc8bdb3cc975cba9036f97a8eeb0301907c950c7
parent60eddb209b5ad13a549ca74a41b7cb38a31da5ef (diff)
Notes
-rw-r--r--share/man/man9/malloc.911
-rw-r--r--sys/kern/kern_malloc.c10
-rw-r--r--sys/sys/malloc.h15
3 files changed, 22 insertions, 14 deletions
diff --git a/share/man/man9/malloc.9 b/share/man/man9/malloc.9
index 674cd30dbb24..bd26600a65f7 100644
--- a/share/man/man9/malloc.9
+++ b/share/man/man9/malloc.9
@@ -29,7 +29,7 @@
.\" $NetBSD: malloc.9,v 1.3 1996/11/11 00:05:11 lukem Exp $
.\" $FreeBSD$
.\"
-.Dd November 19, 2015
+.Dd January 10, 2018
.Dt MALLOC 9
.Os
.Sh NAME
@@ -154,6 +154,7 @@ If the request cannot be immediately fulfilled, the current process is put
to sleep to wait for resources to be released by other processes.
The
.Fn malloc ,
+.Fn mallocarray ,
.Fn realloc ,
and
.Fn reallocf
@@ -162,15 +163,13 @@ functions cannot return
if
.Dv M_WAITOK
is specified.
-The
-.Fn mallocarray
-function can return
-.Dv NULL
if the multiplication of
.Fa nmemb
and
.Fa size
-would cause an integer overflow.
+would cause an integer overflow, the
+.Fn mallocarray
+function induces a panic.
.It Dv M_USE_RESERVE
Indicates that the system can use its reserve of memory to satisfy the
request.
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 94be535a71c9..010b1ee8799b 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -535,18 +535,12 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
return ((void *) va);
}
-/*
- * 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 (1UL << (sizeof(size_t) * 8 / 2))
void *
mallocarray(size_t nmemb, size_t size, struct malloc_type *type, int flags)
{
- if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
- nmemb > 0 && SIZE_MAX / nmemb < size)
- return (NULL);
+ if (WOULD_OVERFLOW(nmemb, size))
+ panic("mallocarray: %zu * %zu overflowed", nmemb, size);
return (malloc(size * nmemb, type, flags));
}
diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h
index 119b2448f7c5..47ca13f5ebd6 100644
--- a/sys/sys/malloc.h
+++ b/sys/sys/malloc.h
@@ -41,6 +41,7 @@
#include <sys/queue.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
+#include <machine/_limits.h>
#define MINALLOCSIZE UMA_SMALLEST_UNIT
@@ -192,6 +193,20 @@ void *reallocf(void *addr, unsigned long size, struct malloc_type *type,
int flags) __result_use_check __alloc_size(2);
struct malloc_type *malloc_desc2type(const char *desc);
+
+/*
+ * 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 (1UL << (sizeof(size_t) * 8 / 2))
+static inline bool
+WOULD_OVERFLOW(size_t nmemb, size_t size)
+{
+
+ return ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && __SIZE_T_MAX / nmemb < size);
+}
+#undef MUL_NO_OVERFLOW
#endif /* _KERNEL */
#endif /* !_SYS_MALLOC_H_ */