summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib/malloc.c
diff options
context:
space:
mode:
authorotto <otto@openbsd.org>2018-11-18 16:15:18 +0000
committerotto <otto@openbsd.org>2018-11-18 16:15:18 +0000
commitf5c5425b42e670459d60a80ea1f4909e4b6f2357 (patch)
tree1811ab5e8ebbf0a77c72b209c9c74201545a683d /lib/libc/stdlib/malloc.c
parentMACHINE_ARCH -> MACHINE to fix syspatch build on macppc and arm64. (diff)
downloadwireguard-openbsd-f5c5425b42e670459d60a80ea1f4909e4b6f2357.tar.xz
wireguard-openbsd-f5c5425b42e670459d60a80ea1f4909e4b6f2357.zip
Implement malloc_usable_size(); ok millert@ deraadt@ and jmc@ for the man page
Diffstat (limited to 'lib/libc/stdlib/malloc.c')
-rw-r--r--lib/libc/stdlib/malloc.c80
1 files changed, 79 insertions, 1 deletions
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)
{