From c09f36897390766ba366d9d7b51ae7f96aa9c1e9 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 10 Jul 2007 11:23:18 -0700 Subject: [PATCH] Fix too-big madvise() call in ibv_madvise_range() When the first memory range found in ibv_madvise_range() is merged with the previous range before entering the loop that calls madvise(), a too-big range could be passed to madvise(). This could lead to trying to madvise() memory that has already been freed and unmapped, which causes madvise() and therefore ibv_reg_mr() to fail. Fix this by making sure we don't madvise() any memory outside the range passed into ibv_madvise_range(). This fixes . Signed-off-by: Roland Dreier --- src/memory.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/memory.c b/src/memory.c index 7f49683..53d86b7 100644 --- a/src/memory.c +++ b/src/memory.c @@ -510,9 +510,24 @@ static int ibv_madvise_range(void *base, size_t size, int advice) if ((inc == -1 && node->refcnt == 0) || (inc == 1 && node->refcnt == 1)) { - ret = madvise((void *) node->start, - node->end - node->start + 1, - advice); + /* + * If this is the first time through the loop, + * and we merged this node with the previous + * one, then we only want to do the madvise() + * on start ... node->end (rather than + * starting at node->start). + * + * Otherwise we end up doing madvise() on + * bigger region than we're being asked to, + * and that may lead to a spurious failure. + */ + if (start > node->start) + ret = madvise((void *) start, node->end - start + 1, + advice); + else + ret = madvise((void *) node->start, + node->end - node->start + 1, + advice); if (ret) goto out; } -- 2.46.0