summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2018-11-10 07:38:43 +0300
committerValentin Bartenev <vbart@nginx.com>2018-11-10 07:38:43 +0300
commit4f4a2d8c63e55401fe0fccb47d747701cdf3171e (patch)
treeecef9f7c0e35044b7013acc9752995f1cb06b2a1
parent4a77c447babd494b66156c43796deabaa47697a3 (diff)
downloadunit-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.c10
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);
}