]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush/mapper: ensure bucket id is valid before indexing buckets array
authorSage Weil <sage@redhat.com>
Wed, 28 Oct 2015 00:55:26 +0000 (20:55 -0400)
committerAbhishek Varshney <abhishek.varshney@flipkart.com>
Wed, 18 Nov 2015 07:11:12 +0000 (12:41 +0530)
We were indexing the buckets array without verifying the index was within
the [0,max_buckets) range.  This could happen because a multistep rule
does not have enough buckets and has CRUSH_ITEM_NONE
for an intermediate result, which would feed in CRUSH_ITEM_NONE and
make us crash.

Fixes: #13477
Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit 976a24a326da8931e689ee22fce35feab5b67b76)

src/crush/mapper.c

index 393bfb22d5bbafd83c20f5953b98c6709b637452..5fc7d33a6dcc643946e71d19400f3079ee26576e 100644 (file)
@@ -888,6 +888,7 @@ int crush_do_rule(const struct crush_map *map,
                        osize = 0;
 
                        for (i = 0; i < wsize; i++) {
+                               int bno;
                                /*
                                 * see CRUSH_N, CRUSH_N_MINUS macros.
                                 * basically, numrep <= 0 means relative to
@@ -900,6 +901,13 @@ int crush_do_rule(const struct crush_map *map,
                                                continue;
                                }
                                j = 0;
+                               /* make sure bucket id is valid */
+                               bno = -1 - w[i];
+                               if (bno < 0 || bno >= map->max_buckets) {
+                                       // w[i] is probably CRUSH_ITEM_NONE
+                                       dprintk("  bad w[i] %d\n", w[i]);
+                                       continue;
+                               }
                                if (firstn) {
                                        int recurse_tries;
                                        if (choose_leaf_tries)
@@ -911,7 +919,7 @@ int crush_do_rule(const struct crush_map *map,
                                                recurse_tries = choose_tries;
                                        osize += crush_choose_firstn(
                                                map,
-                                               map->buckets[-1-w[i]],
+                                               map->buckets[bno],
                                                weight, weight_max,
                                                x, numrep,
                                                curstep->arg2,
@@ -930,7 +938,7 @@ int crush_do_rule(const struct crush_map *map,
                                                    numrep : (result_max-osize));
                                        crush_choose_indep(
                                                map,
-                                               map->buckets[-1-w[i]],
+                                               map->buckets[bno],
                                                weight, weight_max,
                                                x, out_size, numrep,
                                                curstep->arg2,