]> git.openfabrics.org - ~shefty/libibverbs.git/commitdiff
Fix too-big madvise() call in ibv_madvise_range()
authorRoland Dreier <rolandd@cisco.com>
Tue, 10 Jul 2007 18:23:18 +0000 (11:23 -0700)
committerRoland Dreier <rolandd@cisco.com>
Tue, 10 Jul 2007 18:23:18 +0000 (11:23 -0700)
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 <https://bugs.openfabrics.org/show_bug.cgi?id=682>.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
src/memory.c

index 7f4968341378dc978ecc453f48fc9bc367535f2d..53d86b70ef7ba0aa16243a8a724a34665ccbdeb2 100644 (file)
@@ -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;
                }