From 526180b76d9e54f40d0fb9e58b0647a21a7e5f77 Mon Sep 17 00:00:00 2001 From: David Goldblatt Date: Thu, 17 Dec 2020 17:14:30 -0800 Subject: [PATCH] Extent.c: Avoid an rtree NULL-check. The edge case in which pages_map returns (void *)PAGE can trigger an incorrect assertion failure. Avoid it. --- src/extent.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/extent.c b/src/extent.c index 378bc733..c41f17ce 100644 --- a/src/extent.c +++ b/src/extent.c @@ -893,8 +893,22 @@ extent_try_coalesce_impl(tsdn_t *tsdn, pac_t *pac, ehooks_t *ehooks, } /* Try to coalesce backward. */ - edata_t *prev = emap_lock_edata_from_addr(tsdn, pac->emap, - edata_before_get(edata), inactive_only); + edata_t *prev = NULL; + if (edata_before_get(edata) != NULL) { + /* + * This is subtle; the rtree code asserts that its input + * pointer is non-NULL, and this is a useful thing to + * check. But it's possible that edata corresponds to + * an address of (void *)PAGE (in practice, this has + * only been observed on FreeBSD when address-space + * randomization is on, but it could in principle happen + * anywhere). In this case, edata_before_get(edata) is + * NULL, triggering the assert. + */ + prev = emap_lock_edata_from_addr(tsdn, pac->emap, + edata_before_get(edata), inactive_only); + + } if (prev != NULL) { bool can_coalesce = extent_can_coalesce(ecache, edata, prev);