Browse Source

Implement malloc_usable_size(); ok millert@ deraadt@ and jmc@ for the man page

OPENBSD_6_5
otto 5 years ago
parent
commit
ed5636e718
3 changed files with 110 additions and 7 deletions
  1. +2
    -1
      src/include/stdlib.h
  2. +29
    -5
      src/lib/libc/stdlib/malloc.3
  3. +79
    -1
      src/lib/libc/stdlib/malloc.c

+ 2
- 1
src/include/stdlib.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: stdlib.h,v 1.73 2018/11/05 08:23:40 otto Exp $ */
/* $OpenBSD: stdlib.h,v 1.74 2018/11/18 16:15:18 otto Exp $ */
/* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */
/*-
@ -112,6 +112,7 @@ long labs(long);
ldiv_t ldiv(long, long);
void *malloc(size_t);
#if __BSD_VISIBLE
size_t malloc_usable_size(void *);
void freezero(void *, size_t)
__attribute__ ((__bounded__(__buffer__,1,2)));
void *reallocarray(void *, size_t, size_t);


+ 29
- 5
src/lib/libc/stdlib/malloc.3 View File

@ -30,9 +30,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $OpenBSD: malloc.3,v 1.118 2018/11/08 05:58:21 otto Exp $
.\" $OpenBSD: malloc.3,v 1.119 2018/11/18 16:15:18 otto Exp $
.\"
.Dd $Mdocdate: November 8 2018 $
.Dd $Mdocdate: November 18 2018 $
.Dt MALLOC 3
.Os
.Sh NAME
@ -43,7 +43,8 @@
.Nm reallocarray ,
.Nm recallocarray ,
.Nm freezero ,
.Nm aligned_alloc
.Nm aligned_alloc ,
.Nm malloc_usable_size
.Nd memory allocation and deallocation
.Sh SYNOPSIS
.In stdlib.h
@ -63,6 +64,8 @@
.Fn freezero "void *ptr" "size_t size"
.Ft void *
.Fn aligned_alloc "size_t alignment" "size_t size"
.Ft size_t
.Fn malloc_usable_size "void *ptr"
.Vt char *malloc_options ;
.Sh DESCRIPTION
The standard functions
@ -191,7 +194,7 @@ must be a value such that
.Fa size
is the size of the earlier allocation that returned
.Fa ptr ,
otherwise the behaviour is undefined.
otherwise the behavior is undefined.
.Pp
The
.Fn freezero
@ -233,6 +236,25 @@ If
is not a multiple of
.Fa alignment ,
behavior is undefined.
.Pp
The
.Fn malloc_usable_size
function returns the actual size of the allocated memory pointed to by
.Va ptr .
If
.Va ptr
is
.Dv NULL ,
it returns 0.
If
.Va ptr
was never returned by an allocation function or freed before,
the behavior is undefined.
This function should not be relied upon since it exposes some of the internal
workings of the
.Fn malloc
family of functions.
Writing beyond the requested size introduces undefined behavior.
.Sh RETURN VALUES
Upon successful completion, the allocation functions
return a pointer to the allocated space; otherwise,
@ -618,7 +640,9 @@ function appeared in
.Ox 6.2 .
The
.Fn aligned_alloc
function appeared in
and
.Fn malloc_usable_size
functions appeared in
.Ox 6.5 .
.Sh CAVEATS
When using


+ 79
- 1
src/lib/libc/stdlib/malloc.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: malloc.c,v 1.251 2018/11/06 08:01:43 otto Exp $ */
/* $OpenBSD: malloc.c,v 1.252 2018/11/18 16:15:18 otto Exp $ */
/*
* Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
* Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@ -1466,6 +1466,84 @@ freezero(void *ptr, size_t sz)
}
DEF_WEAK(freezero);
static size_t
osize(struct dir_info *argpool, void *p)
{
struct dir_info *pool;
struct region_info *r;
char *saved_function;
size_t sz;
int i;
pool = argpool;
r = find(pool, p);
if (r == NULL) {
if (mopts.malloc_mt) {
for (i = 0; i < _MALLOC_MUTEXES; i++) {
if (i == argpool->mutex)
continue;
pool->active--;
_MALLOC_UNLOCK(pool->mutex);
pool = mopts.malloc_pool[i];
_MALLOC_LOCK(pool->mutex);
pool->active++;
r = find(pool, p);
if (r != NULL) {
saved_function = pool->func;
pool->func = argpool->func;
break;
}
}
}
if (r == NULL)
wrterror(argpool, "bogus pointer (double free?) %p", p);
}
REALSIZE(sz, r);
if (sz > MALLOC_MAXCHUNK) {
if (MALLOC_MOVE_COND(sz))
sz = MALLOC_PAGESIZE - ((char *)p - (char *)r->p);
else
sz = PAGEROUND(sz);
}
if (argpool != pool) {
pool->active--;
pool->func = saved_function;
_MALLOC_UNLOCK(pool->mutex);
_MALLOC_LOCK(argpool->mutex);
argpool->active++;
}
return sz;
}
size_t
malloc_usable_size(void *ptr)
{
struct dir_info *d;
int saved_errno = errno;
size_t sz;
/* This is legal. */
if (ptr == NULL)
return 0;
d = getpool();
if (d == NULL)
wrterror(d, "malloc_usable_size() called before allocation");
_MALLOC_LOCK(d->mutex);
d->func = "malloc_usable_size";
if (d->active++) {
malloc_recurse(d);
return 0;
}
sz = osize(d, ptr);
d->active--;
_MALLOC_UNLOCK(d->mutex);
errno = saved_errno;
return sz;
}
DEF_WEAK(malloc_usable_size);
static void *
orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f)
{


Loading…
Cancel
Save