Date: Sun, 7 Jan 2018 09:55:12 -0800 (PST) From: "Rodney W. Grimes" <freebsd@pdx.rh.CN85.dnsmgr.net> To: Kristof Provost <kp@freebsd.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r327674 - in head: share/man/man9 sys/kern sys/sys Message-ID: <201801071755.w07HtCAU017655@pdx.rh.CN85.dnsmgr.net> In-Reply-To: <201801071321.w07DL2hN064072@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
[ Charset UTF-8 unsupported, converting... ] > Author: kp > Date: Sun Jan 7 13:21:01 2018 > New Revision: 327674 > URL: https://svnweb.freebsd.org/changeset/base/327674 > > Log: > Introduce mallocarray() in the kernel > > Similar to calloc() the mallocarray() function checks for integer > overflows before allocating memory. > It does not zero memory, unless the M_ZERO flag is set. > > Reviewed by: pfg, vangyzen (previous version), imp (previous version) > Obtained from: OpenBSD > Differential Revision: https://reviews.freebsd.org/D13766 > > 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 Sun Jan 7 10:29:15 2018 (r327673) > +++ head/share/man/man9/malloc.9 Sun Jan 7 13:21:01 2018 (r327674) > @@ -45,6 +45,8 @@ > .In sys/malloc.h > .Ft void * > .Fn malloc "unsigned long size" "struct malloc_type *type" "int flags" > +.Ft void * > +.Fn mallocarray "size_t nmemb" "size_t size" "struct malloc_type *type" "int flags" > .Ft void > .Fn free "void *addr" "struct malloc_type *type" > .Ft void * > @@ -64,6 +66,14 @@ object whose size is specified by > .Fa size . > .Pp > The > +.Fn mallocarray > +function allocates uninitialized memory in kernel address space for an > +array of > +.Fa nmemb > +entries whose size is specified by > +.Fa size . > +.Pp > +The > .Fn free > function releases memory at address > .Fa addr > @@ -152,6 +162,15 @@ 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. > .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 Sun Jan 7 10:29:15 2018 (r327673) > +++ head/sys/kern/kern_malloc.c Sun Jan 7 13:21:01 2018 (r327674) > @@ -4,6 +4,7 @@ > * Copyright (c) 1987, 1991, 1993 > * The Regents of the University of California. > * Copyright (c) 2005-2009 Robert N. M. Watson > + * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> (mallocarray) Is this code really over a decade old???? or is this a typo? > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > @@ -532,6 +533,22 @@ malloc(unsigned long size, struct malloc_type *mtp, in > va = redzone_setup(va, osize); > #endif > 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); > + > + return (malloc(size * nmemb, type, flags)); > } > > /* > > Modified: head/sys/sys/malloc.h > ============================================================================== > --- head/sys/sys/malloc.h Sun Jan 7 10:29:15 2018 (r327673) > +++ head/sys/sys/malloc.h Sun Jan 7 13:21:01 2018 (r327674) > @@ -177,6 +177,9 @@ void *contigmalloc(unsigned long size, struct malloc_t > void free(void *addr, struct malloc_type *type); > void *malloc(unsigned long size, struct malloc_type *type, int flags) > __malloc_like __result_use_check __alloc_size(1); > +void *mallocarray(size_t nmemb, size_t size, struct malloc_type *type, > + int flags) __malloc_like __result_use_check > + __alloc_size(1) __alloc_size(2); > void malloc_init(void *); > int malloc_last_fail(void); > void malloc_type_allocated(struct malloc_type *type, unsigned long size); > > -- Rod Grimes rgrimes@freebsd.org
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201801071755.w07HtCAU017655>