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
This commit is contained in:
parent
6d5343e38e
commit
fd91e076c1
@ -45,6 +45,8 @@
|
|||||||
.In sys/malloc.h
|
.In sys/malloc.h
|
||||||
.Ft void *
|
.Ft void *
|
||||||
.Fn malloc "unsigned long size" "struct malloc_type *type" "int flags"
|
.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
|
.Ft void
|
||||||
.Fn free "void *addr" "struct malloc_type *type"
|
.Fn free "void *addr" "struct malloc_type *type"
|
||||||
.Ft void *
|
.Ft void *
|
||||||
@ -64,6 +66,14 @@ object whose size is specified by
|
|||||||
.Fa size .
|
.Fa size .
|
||||||
.Pp
|
.Pp
|
||||||
The
|
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
|
.Fn free
|
||||||
function releases memory at address
|
function releases memory at address
|
||||||
.Fa addr
|
.Fa addr
|
||||||
@ -152,6 +162,15 @@ functions cannot return
|
|||||||
if
|
if
|
||||||
.Dv M_WAITOK
|
.Dv M_WAITOK
|
||||||
is specified.
|
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
|
.It Dv M_USE_RESERVE
|
||||||
Indicates that the system can use its reserve of memory to satisfy the
|
Indicates that the system can use its reserve of memory to satisfy the
|
||||||
request.
|
request.
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* Copyright (c) 1987, 1991, 1993
|
* Copyright (c) 1987, 1991, 1993
|
||||||
* The Regents of the University of California.
|
* The Regents of the University of California.
|
||||||
* Copyright (c) 2005-2009 Robert N. M. Watson
|
* Copyright (c) 2005-2009 Robert N. M. Watson
|
||||||
|
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> (mallocarray)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -534,6 +535,22 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
|
|||||||
return ((void *) va);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free:
|
* free:
|
||||||
*
|
*
|
||||||
|
@ -177,6 +177,9 @@ void *contigmalloc(unsigned long size, struct malloc_type *type, int flags,
|
|||||||
void free(void *addr, struct malloc_type *type);
|
void free(void *addr, struct malloc_type *type);
|
||||||
void *malloc(unsigned long size, struct malloc_type *type, int flags)
|
void *malloc(unsigned long size, struct malloc_type *type, int flags)
|
||||||
__malloc_like __result_use_check __alloc_size(1);
|
__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 *);
|
void malloc_init(void *);
|
||||||
int malloc_last_fail(void);
|
int malloc_last_fail(void);
|
||||||
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
|
void malloc_type_allocated(struct malloc_type *type, unsigned long size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user