summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2018-11-18 16:15:19 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2018-11-18 16:15:19 +0000
commit19c707d39f9cded07862cd5957e1b6200166aaf5 (patch)
tree11bb3b1d7499b83b15efb96feb99ce54808b7931
parenta4a7902489e19d8dd3256311e4687735b73f2851 (diff)
Implement malloc_usable_size(); ok millert@ deraadt@ and jmc@ for the man page
-rw-r--r--include/stdlib.h3
-rw-r--r--lib/libc/Symbols.list1
-rw-r--r--lib/libc/hidden/stdlib.h3
-rw-r--r--lib/libc/shlib_version2
-rw-r--r--lib/libc/stdlib/malloc.334
-rw-r--r--lib/libc/stdlib/malloc.c80
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)
{