Author: cem
Date: Wed Jan 10 21:49:45 2018
New Revision: 327796
URL: https://svnweb.freebsd.org/changeset/base/327796
Log:
  mallocarray(9): panic if the requested allocation would overflow
  
  Additionally, move the overflow check logic out to WOULD_OVERFLOW() for
  consumers to have a common means of testing for overflowing allocations.
  WOULD_OVERFLOW() should be a secondary check -- on 64-bit platforms, just
  because an allocation won't overflow size_t does not mean it is a sane size
  to request.  Callers should be imposing reasonable allocation limits far,
  far, below overflow.
  
  Discussed with:       emaste, jhb, kp
  Sponsored by: Dell EMC Isilon

Modified:
  head/share/man/man9/malloc.9
  head/sys/kern/kern_malloc.c
  head/sys/sys/malloc.h

Modified: head/share/man/man9/malloc.9
==============================================================================
--- head/share/man/man9/malloc.9        Wed Jan 10 21:40:36 2018        
(r327795)
+++ head/share/man/man9/malloc.9        Wed Jan 10 21:49:45 2018        
(r327796)
@@ -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 cu
 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.

Modified: head/sys/kern/kern_malloc.c
==============================================================================
--- head/sys/kern/kern_malloc.c Wed Jan 10 21:40:36 2018        (r327795)
+++ head/sys/kern/kern_malloc.c Wed Jan 10 21:49:45 2018        (r327796)
@@ -535,18 +535,12 @@ malloc(unsigned long size, struct malloc_type *mtp, in
        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));
 }

Modified: head/sys/sys/malloc.h
==============================================================================
--- head/sys/sys/malloc.h       Wed Jan 10 21:40:36 2018        (r327795)
+++ head/sys/sys/malloc.h       Wed Jan 10 21:49:45 2018        (r327796)
@@ -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 
            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_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to