aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-01-31 08:35:59 -0500
committerIlya Dryomov <idryomov@gmail.com>2016-02-04 12:25:23 -0500
commitf224a6915f266921507bb6e50a82f87a3de5b4b5 (patch)
tree01ec95389acdeba3651745a1a9457d976c011152
parentdb6aed70235b35a113e1b0e81cb293fd2e92de0f (diff)
crush: ensure bucket id is valid before indexing buckets array
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. Reflects ceph.git commit 976a24a326da8931e689ee22fce35feab5b67b76. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Sage Weil <sage@redhat.com>
-rw-r--r--net/ceph/crush/mapper.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c
index 393bfb22d5bb..97ecf6f262aa 100644
--- a/net/ceph/crush/mapper.c
+++ b/net/ceph/crush/mapper.c
@@ -888,6 +888,7 @@ int crush_do_rule(const struct crush_map *map,
888 osize = 0; 888 osize = 0;
889 889
890 for (i = 0; i < wsize; i++) { 890 for (i = 0; i < wsize; i++) {
891 int bno;
891 /* 892 /*
892 * see CRUSH_N, CRUSH_N_MINUS macros. 893 * see CRUSH_N, CRUSH_N_MINUS macros.
893 * basically, numrep <= 0 means relative to 894 * basically, numrep <= 0 means relative to
@@ -900,6 +901,13 @@ int crush_do_rule(const struct crush_map *map,
900 continue; 901 continue;
901 } 902 }
902 j = 0; 903 j = 0;
904 /* make sure bucket id is valid */
905 bno = -1 - w[i];
906 if (bno < 0 || bno >= map->max_buckets) {
907 /* w[i] is probably CRUSH_ITEM_NONE */
908 dprintk(" bad w[i] %d\n", w[i]);
909 continue;
910 }
903 if (firstn) { 911 if (firstn) {
904 int recurse_tries; 912 int recurse_tries;
905 if (choose_leaf_tries) 913 if (choose_leaf_tries)
@@ -911,7 +919,7 @@ int crush_do_rule(const struct crush_map *map,
911 recurse_tries = choose_tries; 919 recurse_tries = choose_tries;
912 osize += crush_choose_firstn( 920 osize += crush_choose_firstn(
913 map, 921 map,
914 map->buckets[-1-w[i]], 922 map->buckets[bno],
915 weight, weight_max, 923 weight, weight_max,
916 x, numrep, 924 x, numrep,
917 curstep->arg2, 925 curstep->arg2,
@@ -930,7 +938,7 @@ int crush_do_rule(const struct crush_map *map,
930 numrep : (result_max-osize)); 938 numrep : (result_max-osize));
931 crush_choose_indep( 939 crush_choose_indep(
932 map, 940 map,
933 map->buckets[-1-w[i]], 941 map->buckets[bno],
934 weight, weight_max, 942 weight, weight_max,
935 x, out_size, numrep, 943 x, out_size, numrep,
936 curstep->arg2, 944 curstep->arg2,