diff options
| -rw-r--r-- | net/ceph/osdmap.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 69bc4bf89e3e..4543b9aba40c 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
| @@ -654,6 +654,24 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) | |||
| 654 | return 0; | 654 | return 0; |
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | static int __decode_pgid(void **p, void *end, struct ceph_pg *pg) | ||
| 658 | { | ||
| 659 | u8 v; | ||
| 660 | |||
| 661 | ceph_decode_need(p, end, 1+8+4+4, bad); | ||
| 662 | v = ceph_decode_8(p); | ||
| 663 | if (v != 1) | ||
| 664 | goto bad; | ||
| 665 | pg->pool = ceph_decode_64(p); | ||
| 666 | pg->seed = ceph_decode_32(p); | ||
| 667 | *p += 4; /* skip preferred */ | ||
| 668 | return 0; | ||
| 669 | |||
| 670 | bad: | ||
| 671 | dout("error decoding pgid\n"); | ||
| 672 | return -EINVAL; | ||
| 673 | } | ||
| 674 | |||
| 657 | /* | 675 | /* |
| 658 | * decode a full map. | 676 | * decode a full map. |
| 659 | */ | 677 | */ |
| @@ -745,13 +763,12 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
| 745 | for (i = 0; i < len; i++) { | 763 | for (i = 0; i < len; i++) { |
| 746 | int n, j; | 764 | int n, j; |
| 747 | struct ceph_pg pgid; | 765 | struct ceph_pg pgid; |
| 748 | struct ceph_pg_v1 pgid_v1; | ||
| 749 | struct ceph_pg_mapping *pg; | 766 | struct ceph_pg_mapping *pg; |
| 750 | 767 | ||
| 751 | ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad); | 768 | err = __decode_pgid(p, end, &pgid); |
| 752 | ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1)); | 769 | if (err) |
| 753 | pgid.pool = le32_to_cpu(pgid_v1.pool); | 770 | goto bad; |
| 754 | pgid.seed = le16_to_cpu(pgid_v1.ps); | 771 | ceph_decode_need(p, end, sizeof(u32), bad); |
| 755 | n = ceph_decode_32(p); | 772 | n = ceph_decode_32(p); |
| 756 | err = -EINVAL; | 773 | err = -EINVAL; |
| 757 | if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32)) | 774 | if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32)) |
| @@ -818,8 +835,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
| 818 | u16 version; | 835 | u16 version; |
| 819 | 836 | ||
| 820 | ceph_decode_16_safe(p, end, version, bad); | 837 | ceph_decode_16_safe(p, end, version, bad); |
| 821 | if (version > 6) { | 838 | if (version != 6) { |
| 822 | pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6); | 839 | pr_warning("got unknown v %d != 6 of inc osdmap\n", version); |
| 823 | goto bad; | 840 | goto bad; |
| 824 | } | 841 | } |
| 825 | 842 | ||
| @@ -963,15 +980,14 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
| 963 | while (len--) { | 980 | while (len--) { |
| 964 | struct ceph_pg_mapping *pg; | 981 | struct ceph_pg_mapping *pg; |
| 965 | int j; | 982 | int j; |
| 966 | struct ceph_pg_v1 pgid_v1; | ||
| 967 | struct ceph_pg pgid; | 983 | struct ceph_pg pgid; |
| 968 | u32 pglen; | 984 | u32 pglen; |
| 969 | ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad); | ||
| 970 | ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1)); | ||
| 971 | pgid.pool = le32_to_cpu(pgid_v1.pool); | ||
| 972 | pgid.seed = le16_to_cpu(pgid_v1.ps); | ||
| 973 | pglen = ceph_decode_32(p); | ||
| 974 | 985 | ||
| 986 | err = __decode_pgid(p, end, &pgid); | ||
| 987 | if (err) | ||
| 988 | goto bad; | ||
| 989 | ceph_decode_need(p, end, sizeof(u32), bad); | ||
| 990 | pglen = ceph_decode_32(p); | ||
| 975 | if (pglen) { | 991 | if (pglen) { |
| 976 | ceph_decode_need(p, end, pglen*sizeof(u32), bad); | 992 | ceph_decode_need(p, end, pglen*sizeof(u32), bad); |
| 977 | 993 | ||
