diff options
author | otto <> | 2018-11-18 16:15:18 +0000 |
---|---|---|
committer | otto <> | 2018-11-18 16:15:18 +0000 |
commit | e03dc031fa67e7d982aeacfea51fb4615d4783b6 (patch) | |
tree | 8f4e932865189bdd3f6d7c230def20c4842f4c69 /src/lib | |
parent | 041aeb91a95a5be54d73153ff1a3efac4df4bc99 (diff) | |
download | openbsd-e03dc031fa67e7d982aeacfea51fb4615d4783b6.tar.gz openbsd-e03dc031fa67e7d982aeacfea51fb4615d4783b6.tar.bz2 openbsd-e03dc031fa67e7d982aeacfea51fb4615d4783b6.zip |
Implement malloc_usable_size(); ok millert@ deraadt@ and jmc@ for the man page
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libc/stdlib/malloc.3 | 34 | ||||
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 80 |
2 files changed, 108 insertions, 6 deletions
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3 index 35222a15ce..c1776f61cb 100644 --- a/src/lib/libc/stdlib/malloc.3 +++ b/src/lib/libc/stdlib/malloc.3 | |||
@@ -30,9 +30,9 @@ | |||
30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 30 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
31 | .\" SUCH DAMAGE. | 31 | .\" SUCH DAMAGE. |
32 | .\" | 32 | .\" |
33 | .\" $OpenBSD: malloc.3,v 1.118 2018/11/08 05:58:21 otto Exp $ | 33 | .\" $OpenBSD: malloc.3,v 1.119 2018/11/18 16:15:18 otto Exp $ |
34 | .\" | 34 | .\" |
35 | .Dd $Mdocdate: November 8 2018 $ | 35 | .Dd $Mdocdate: November 18 2018 $ |
36 | .Dt MALLOC 3 | 36 | .Dt MALLOC 3 |
37 | .Os | 37 | .Os |
38 | .Sh NAME | 38 | .Sh NAME |
@@ -43,7 +43,8 @@ | |||
43 | .Nm reallocarray , | 43 | .Nm reallocarray , |
44 | .Nm recallocarray , | 44 | .Nm recallocarray , |
45 | .Nm freezero , | 45 | .Nm freezero , |
46 | .Nm aligned_alloc | 46 | .Nm aligned_alloc , |
47 | .Nm malloc_usable_size | ||
47 | .Nd memory allocation and deallocation | 48 | .Nd memory allocation and deallocation |
48 | .Sh SYNOPSIS | 49 | .Sh SYNOPSIS |
49 | .In stdlib.h | 50 | .In stdlib.h |
@@ -63,6 +64,8 @@ | |||
63 | .Fn freezero "void *ptr" "size_t size" | 64 | .Fn freezero "void *ptr" "size_t size" |
64 | .Ft void * | 65 | .Ft void * |
65 | .Fn aligned_alloc "size_t alignment" "size_t size" | 66 | .Fn aligned_alloc "size_t alignment" "size_t size" |
67 | .Ft size_t | ||
68 | .Fn malloc_usable_size "void *ptr" | ||
66 | .Vt char *malloc_options ; | 69 | .Vt char *malloc_options ; |
67 | .Sh DESCRIPTION | 70 | .Sh DESCRIPTION |
68 | The standard functions | 71 | The standard functions |
@@ -191,7 +194,7 @@ must be a value such that | |||
191 | .Fa size | 194 | .Fa size |
192 | is the size of the earlier allocation that returned | 195 | is the size of the earlier allocation that returned |
193 | .Fa ptr , | 196 | .Fa ptr , |
194 | otherwise the behaviour is undefined. | 197 | otherwise the behavior is undefined. |
195 | .Pp | 198 | .Pp |
196 | The | 199 | The |
197 | .Fn freezero | 200 | .Fn freezero |
@@ -233,6 +236,25 @@ If | |||
233 | is not a multiple of | 236 | is not a multiple of |
234 | .Fa alignment , | 237 | .Fa alignment , |
235 | behavior is undefined. | 238 | behavior is undefined. |
239 | .Pp | ||
240 | The | ||
241 | .Fn malloc_usable_size | ||
242 | function returns the actual size of the allocated memory pointed to by | ||
243 | .Va ptr . | ||
244 | If | ||
245 | .Va ptr | ||
246 | is | ||
247 | .Dv NULL , | ||
248 | it returns 0. | ||
249 | If | ||
250 | .Va ptr | ||
251 | was never returned by an allocation function or freed before, | ||
252 | the behavior is undefined. | ||
253 | This function should not be relied upon since it exposes some of the internal | ||
254 | workings of the | ||
255 | .Fn malloc | ||
256 | family of functions. | ||
257 | Writing beyond the requested size introduces undefined behavior. | ||
236 | .Sh RETURN VALUES | 258 | .Sh RETURN VALUES |
237 | Upon successful completion, the allocation functions | 259 | Upon successful completion, the allocation functions |
238 | return a pointer to the allocated space; otherwise, | 260 | return a pointer to the allocated space; otherwise, |
@@ -618,7 +640,9 @@ function appeared in | |||
618 | .Ox 6.2 . | 640 | .Ox 6.2 . |
619 | The | 641 | The |
620 | .Fn aligned_alloc | 642 | .Fn aligned_alloc |
621 | function appeared in | 643 | and |
644 | .Fn malloc_usable_size | ||
645 | functions appeared in | ||
622 | .Ox 6.5 . | 646 | .Ox 6.5 . |
623 | .Sh CAVEATS | 647 | .Sh CAVEATS |
624 | When using | 648 | When using |
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index af9cf39199..ee4d4c055e 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: malloc.c,v 1.251 2018/11/06 08:01:43 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.252 2018/11/18 16:15:18 otto Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> |
4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> | 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> |
@@ -1466,6 +1466,84 @@ freezero(void *ptr, size_t sz) | |||
1466 | } | 1466 | } |
1467 | DEF_WEAK(freezero); | 1467 | DEF_WEAK(freezero); |
1468 | 1468 | ||
1469 | static size_t | ||
1470 | osize(struct dir_info *argpool, void *p) | ||
1471 | { | ||
1472 | struct dir_info *pool; | ||
1473 | struct region_info *r; | ||
1474 | char *saved_function; | ||
1475 | size_t sz; | ||
1476 | int i; | ||
1477 | |||
1478 | pool = argpool; | ||
1479 | r = find(pool, p); | ||
1480 | if (r == NULL) { | ||
1481 | if (mopts.malloc_mt) { | ||
1482 | for (i = 0; i < _MALLOC_MUTEXES; i++) { | ||
1483 | if (i == argpool->mutex) | ||
1484 | continue; | ||
1485 | pool->active--; | ||
1486 | _MALLOC_UNLOCK(pool->mutex); | ||
1487 | pool = mopts.malloc_pool[i]; | ||
1488 | _MALLOC_LOCK(pool->mutex); | ||
1489 | pool->active++; | ||
1490 | r = find(pool, p); | ||
1491 | if (r != NULL) { | ||
1492 | saved_function = pool->func; | ||
1493 | pool->func = argpool->func; | ||
1494 | break; | ||
1495 | } | ||
1496 | } | ||
1497 | } | ||
1498 | if (r == NULL) | ||
1499 | wrterror(argpool, "bogus pointer (double free?) %p", p); | ||
1500 | } | ||
1501 | |||
1502 | REALSIZE(sz, r); | ||
1503 | if (sz > MALLOC_MAXCHUNK) { | ||
1504 | if (MALLOC_MOVE_COND(sz)) | ||
1505 | sz = MALLOC_PAGESIZE - ((char *)p - (char *)r->p); | ||
1506 | else | ||
1507 | sz = PAGEROUND(sz); | ||
1508 | } | ||
1509 | if (argpool != pool) { | ||
1510 | pool->active--; | ||
1511 | pool->func = saved_function; | ||
1512 | _MALLOC_UNLOCK(pool->mutex); | ||
1513 | _MALLOC_LOCK(argpool->mutex); | ||
1514 | argpool->active++; | ||
1515 | } | ||
1516 | return sz; | ||
1517 | } | ||
1518 | |||
1519 | size_t | ||
1520 | malloc_usable_size(void *ptr) | ||
1521 | { | ||
1522 | struct dir_info *d; | ||
1523 | int saved_errno = errno; | ||
1524 | size_t sz; | ||
1525 | |||
1526 | /* This is legal. */ | ||
1527 | if (ptr == NULL) | ||
1528 | return 0; | ||
1529 | |||
1530 | d = getpool(); | ||
1531 | if (d == NULL) | ||
1532 | wrterror(d, "malloc_usable_size() called before allocation"); | ||
1533 | _MALLOC_LOCK(d->mutex); | ||
1534 | d->func = "malloc_usable_size"; | ||
1535 | if (d->active++) { | ||
1536 | malloc_recurse(d); | ||
1537 | return 0; | ||
1538 | } | ||
1539 | sz = osize(d, ptr); | ||
1540 | d->active--; | ||
1541 | _MALLOC_UNLOCK(d->mutex); | ||
1542 | errno = saved_errno; | ||
1543 | return sz; | ||
1544 | } | ||
1545 | DEF_WEAK(malloc_usable_size); | ||
1546 | |||
1469 | static void * | 1547 | static void * |
1470 | orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f) | 1548 | orealloc(struct dir_info *argpool, void *p, size_t newsz, void *f) |
1471 | { | 1549 | { |