Skip site navigation (1)Skip section navigation (2)
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>