]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: pass weight vector size to map function
authorSage Weil <sage@inktank.com>
Sat, 12 May 2012 21:59:55 +0000 (14:59 -0700)
committerSage Weil <sage@newdream.net>
Mon, 14 May 2012 18:24:32 +0000 (11:24 -0700)
Pass the size of the weight vector into crush_do_rule() to ensure that we
don't access values past the end.  This can happen if the caller misbehaves
and passes a weight vector that is smaller than max_devices.

Currently the monitor tries to prevent that from happening, but this will
gracefully tolerate previous bad osdmaps that got into this state.  It's
also a bit more defensive.

Signed-off-by: Sage Weil <sage@inktank.com>
src/crush/CrushWrapper.h
src/crush/mapper.c
src/crush/mapper.h

index b9f6675dba880d1bddb3672f5da51a5f744ed5ac..ed6aaef4a9fd93e9319948a58073ef68e1b86f70 100644 (file)
@@ -471,7 +471,7 @@ public:
   void do_rule(int rule, int x, vector<int>& out, int maxout,
               const vector<__u32>& weight) const {
     int rawout[maxout];
-    int numrep = crush_do_rule(crush, rule, x, rawout, maxout, &weight[0]);
+    int numrep = crush_do_rule(crush, rule, x, rawout, maxout, &weight[0], weight.size());
     if (numrep < 0)
       numrep = 0;
     out.resize(numrep);
index 88575778ba1206550346b67d85e4256d620cdc23..94d5dd30d7228fbaa96427605d581c1c5ef0a0c0 100644 (file)
@@ -263,8 +263,10 @@ static int crush_bucket_choose(struct crush_bucket *in, int x, int r)
  * true if device is marked "out" (failed, fully offloaded)
  * of the cluster
  */
-static int is_out(const struct crush_map *map, const __u32 *weight, int item, int x)
+static int is_out(const struct crush_map *map, const __u32 *weight, int weight_max, int item, int x)
 {
+       if (item >= weight_max)
+               return 1;
        if (weight[item] >= 0x10000)
                return 0;
        if (weight[item] == 0)
@@ -290,7 +292,7 @@ static int is_out(const struct crush_map *map, const __u32 *weight, int item, in
  */
 static int crush_choose(const struct crush_map *map,
                        struct crush_bucket *bucket,
-                       const __u32 *weight,
+                       const __u32 *weight, int weight_max,
                        int x, int numrep, int type,
                        int *out, int outpos,
                        int firstn, int recurse_to_leaf,
@@ -394,7 +396,7 @@ static int crush_choose(const struct crush_map *map,
                                        if (item < 0) {
                                                if (crush_choose(map,
                                                         map->buckets[-1-item],
-                                                        weight,
+                                                        weight, weight_max,
                                                         x, outpos+1, 0,
                                                         out2, outpos,
                                                         firstn, 0,
@@ -410,7 +412,7 @@ static int crush_choose(const struct crush_map *map,
                                if (!reject) {
                                        /* out? */
                                        if (itemtype == 0)
-                                               reject = is_out(map, weight,
+                                               reject = is_out(map, weight, weight_max,
                                                                item, x);
                                        else
                                                reject = 0;
@@ -466,7 +468,7 @@ reject:
  */
 int crush_do_rule(const struct crush_map *map,
                  int ruleno, int x, int *result, int result_max,
-                 const __u32 *weight)
+                 const __u32 *weight, int weight_max)
 {
        int result_len;
        int a[CRUSH_MAX_SET];
@@ -537,7 +539,7 @@ int crush_do_rule(const struct crush_map *map,
                                j = 0;
                                osize += crush_choose(map,
                                                      map->buckets[-1-w[i]],
-                                                     weight,
+                                                     weight, weight_max,
                                                      x, numrep,
                                                      curstep->arg2,
                                                      o+osize, j,
index 71d79f44a7d0753faeb61a3072efdbacc1aa2371..73f3febbf3e4cf17bc342b1272d9cf1ad8bf8e0d 100644 (file)
@@ -14,6 +14,6 @@ extern int crush_find_rule(const struct crush_map *map, int ruleset, int type, i
 extern int crush_do_rule(const struct crush_map *map,
                         int ruleno,
                         int x, int *result, int result_max,
-                        const __u32 *weights);
+                        const __u32 *weights, int weight_max);
 
 #endif