diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2015-06-12 04:20:03 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-06-25 04:49:31 -0400 |
commit | 8f529795bace5d6263b134f4ff3adccfc0a0cce6 (patch) | |
tree | 46f53222d34baeded01d146b1f223d33146c4e2a | |
parent | 687265e5a885d6308f5d73e738efe3c2674fa218 (diff) |
crush: fix crash from invalid 'take' argument
Verify that the 'take' argument is a valid device or bucket.
Otherwise ignore it (do not add the value to the working vector).
Reflects ceph.git commit 9324d0a1af61e1c234cc48e2175b4e6320fff8f4.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r-- | net/ceph/crush/mapper.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c index 5b47736d27d9..7568cb59b9e5 100644 --- a/net/ceph/crush/mapper.c +++ b/net/ceph/crush/mapper.c | |||
@@ -790,8 +790,15 @@ int crush_do_rule(const struct crush_map *map, | |||
790 | 790 | ||
791 | switch (curstep->op) { | 791 | switch (curstep->op) { |
792 | case CRUSH_RULE_TAKE: | 792 | case CRUSH_RULE_TAKE: |
793 | w[0] = curstep->arg1; | 793 | if ((curstep->arg1 >= 0 && |
794 | wsize = 1; | 794 | curstep->arg1 < map->max_devices) || |
795 | (-1-curstep->arg1 < map->max_buckets && | ||
796 | map->buckets[-1-curstep->arg1])) { | ||
797 | w[0] = curstep->arg1; | ||
798 | wsize = 1; | ||
799 | } else { | ||
800 | dprintk(" bad take value %d\n", curstep->arg1); | ||
801 | } | ||
795 | break; | 802 | break; |
796 | 803 | ||
797 | case CRUSH_RULE_SET_CHOOSE_TRIES: | 804 | case CRUSH_RULE_SET_CHOOSE_TRIES: |