diff options
author | Valentin Bartenev <vbart@nginx.com> | 2018-11-10 07:38:43 +0300 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2018-11-10 07:38:43 +0300 |
commit | 4f4a2d8c63e55401fe0fccb47d747701cdf3171e (patch) | |
tree | ecef9f7c0e35044b7013acc9752995f1cb06b2a1 | |
parent | 4a77c447babd494b66156c43796deabaa47697a3 (diff) | |
download | unit-4f4a2d8c63e55401fe0fccb47d747701cdf3171e.tar.gz unit-4f4a2d8c63e55401fe0fccb47d747701cdf3171e.tar.bz2 |
Fixed "freed pointer is out of pool" alerts.
The issue was caused by misplacement of allocated blocks in rbtree due
to broken comparison function if the distance between two allocations
did not fit into intptr_t. As the result, nxt_mp_free() could have
failed to find the allocation.
In particular, it was mostly observed when Unit was compiled with
musl C library on 32-bits systems.
This closes #118 issue on GitHub.
-rw-r--r-- | src/nxt_mp.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/nxt_mp.c b/src/nxt_mp.c index a0f19ac2..5c1a4d00 100644 --- a/src/nxt_mp.c +++ b/src/nxt_mp.c @@ -768,7 +768,15 @@ nxt_mp_rbtree_compare(nxt_rbtree_node_t *node1, nxt_rbtree_node_t *node2) block1 = (nxt_mp_block_t *) node1; block2 = (nxt_mp_block_t *) node2; - return (uintptr_t) block1->start - (uintptr_t) block2->start; + /* + * Shifting is necessary to prevent overflow of intptr_t when block1->start + * is much greater than block2->start or vice versa. + * + * It is safe to drop one bit since there cannot be adjacent addresses + * because of alignments and allocation sizes. Effectively this reduces + * the absolute values to fit into the magnitude of intptr_t. + */ + return ((uintptr_t) block1->start >> 1) - ((uintptr_t) block2->start >> 1); } |