diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2018-11-18 16:15:19 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2018-11-18 16:15:19 +0000 |
commit | 19c707d39f9cded07862cd5957e1b6200166aaf5 (patch) | |
tree | 11bb3b1d7499b83b15efb96feb99ce54808b7931 | |
parent | a4a7902489e19d8dd3256311e4687735b73f2851 (diff) |
Implement malloc_usable_size(); ok millert@ deraadt@ and jmc@ for the man page
-rw-r--r-- | include/stdlib.h | 3 | ||||
-rw-r--r-- | lib/libc/Symbols.list | 1 | ||||
-rw-r--r-- | lib/libc/hidden/stdlib.h | 3 | ||||
-rw-r--r-- | lib/libc/shlib_version | 2 | ||||
-rw-r--r-- | lib/libc/stdlib/malloc.3 | 34 | ||||
-rw-r--r-- | lib/libc/stdlib/malloc.c | 80 |
6 files changed, 114 insertions, 9 deletions
diff --git a/include/stdlib.h b/include/stdlib.h index d546444c1d7..b0f3dd14782 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -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); diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list index 15c4fff6c2b..8210ebcda20 100644 --- a/lib/libc/Symbols.list +++ b/lib/libc/Symbols.list @@ -1527,6 +1527,7 @@ lldiv lsearch malloc malloc_options +malloc_usable_size _malloc_init mergesort optarg diff --git a/lib/libc/hidden/stdlib.h b/lib/libc/hidden/stdlib.h index 8454304c41d..87858ad2738 100644 --- a/lib/libc/hidden/stdlib.h +++ b/lib/libc/hidden/stdlib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stdlib.h,v 1.13 2018/11/05 08:23:40 otto Exp $ */ +/* $OpenBSD: stdlib.h,v 1.14 2018/11/18 16:15:18 otto Exp $ */ /* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */ /*- @@ -105,6 +105,7 @@ PROTO_STD_DEPRECATED(llabs); PROTO_STD_DEPRECATED(lldiv); PROTO_DEPRECATED(lrand48); /*PROTO_NORMAL(malloc); not yet, breaks emacs */ +PROTO_DEPRECATED(malloc_usable_size); PROTO_STD_DEPRECATED(mblen); PROTO_STD_DEPRECATED(mbstowcs); PROTO_STD_DEPRECATED(mbtowc); diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 2ea5756d25d..222d38e7d8f 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ major=92 -minor=7 +minor=8 # note: If changes were made to include/thread_private.h or if system # calls were added/changed then librthread/shlib_version also be updated. diff --git a/lib/libc/stdlib/malloc.3 b/lib/libc/stdlib/malloc.3 index 35222a15cee..c1776f61cb8 100644 --- a/lib/libc/stdlib/malloc.3 +++ b/lib/libc/stdlib/malloc.3 @@ -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 diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index af9cf39199d..ee4d4c055e9 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -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) { |