aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2012-10-29 14:01:42 -0400
committerAlex Elder <elder@inktank.com>2012-10-30 09:21:05 -0400
commit0ed7285e0001b960c888e5455ae982025210ed3d (patch)
tree4ca3c1faa4d7bc8064d6f0fb609dd3cd568c2554 /net
parent069a4b5690a952e74157fd489833c71c73f012b3 (diff)
libceph: fix osdmap decode error paths
Ensure that we set the err value correctly so that we do not pass a 0 value to ERR_PTR and confuse the calling code. (In particular, osd_client.c handle_map() will BUG(!newmap)). Signed-off-by: Sage Weil <sage@inktank.com> Reviewed-by: Alex Elder <elder@inktank.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/osdmap.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 5433fb0eb3c6..f552aa48fd9e 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -645,10 +645,12 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
645 ceph_decode_32_safe(p, end, max, bad); 645 ceph_decode_32_safe(p, end, max, bad);
646 while (max--) { 646 while (max--) {
647 ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); 647 ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
648 err = -ENOMEM;
648 pi = kzalloc(sizeof(*pi), GFP_NOFS); 649 pi = kzalloc(sizeof(*pi), GFP_NOFS);
649 if (!pi) 650 if (!pi)
650 goto bad; 651 goto bad;
651 pi->id = ceph_decode_32(p); 652 pi->id = ceph_decode_32(p);
653 err = -EINVAL;
652 ev = ceph_decode_8(p); /* encoding version */ 654 ev = ceph_decode_8(p); /* encoding version */
653 if (ev > CEPH_PG_POOL_VERSION) { 655 if (ev > CEPH_PG_POOL_VERSION) {
654 pr_warning("got unknown v %d > %d of ceph_pg_pool\n", 656 pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
@@ -664,8 +666,13 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
664 __insert_pg_pool(&map->pg_pools, pi); 666 __insert_pg_pool(&map->pg_pools, pi);
665 } 667 }
666 668
667 if (version >= 5 && __decode_pool_names(p, end, map) < 0) 669 if (version >= 5) {
668 goto bad; 670 err = __decode_pool_names(p, end, map);
671 if (err < 0) {
672 dout("fail to decode pool names");
673 goto bad;
674 }
675 }
669 676
670 ceph_decode_32_safe(p, end, map->pool_max, bad); 677 ceph_decode_32_safe(p, end, map->pool_max, bad);
671 678
@@ -745,7 +752,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
745 return map; 752 return map;
746 753
747bad: 754bad:
748 dout("osdmap_decode fail\n"); 755 dout("osdmap_decode fail err %d\n", err);
749 ceph_osdmap_destroy(map); 756 ceph_osdmap_destroy(map);
750 return ERR_PTR(err); 757 return ERR_PTR(err);
751} 758}
@@ -839,6 +846,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
839 if (ev > CEPH_PG_POOL_VERSION) { 846 if (ev > CEPH_PG_POOL_VERSION) {
840 pr_warning("got unknown v %d > %d of ceph_pg_pool\n", 847 pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
841 ev, CEPH_PG_POOL_VERSION); 848 ev, CEPH_PG_POOL_VERSION);
849 err = -EINVAL;
842 goto bad; 850 goto bad;
843 } 851 }
844 pi = __lookup_pg_pool(&map->pg_pools, pool); 852 pi = __lookup_pg_pool(&map->pg_pools, pool);
@@ -855,8 +863,11 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
855 if (err < 0) 863 if (err < 0)
856 goto bad; 864 goto bad;
857 } 865 }
858 if (version >= 5 && __decode_pool_names(p, end, map) < 0) 866 if (version >= 5) {
859 goto bad; 867 err = __decode_pool_names(p, end, map);
868 if (err < 0)
869 goto bad;
870 }
860 871
861 /* old_pool */ 872 /* old_pool */
862 ceph_decode_32_safe(p, end, len, bad); 873 ceph_decode_32_safe(p, end, len, bad);
@@ -932,15 +943,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
932 (void) __remove_pg_mapping(&map->pg_temp, pgid); 943 (void) __remove_pg_mapping(&map->pg_temp, pgid);
933 944
934 /* insert */ 945 /* insert */
935 if (pglen > (UINT_MAX - sizeof(*pg)) / sizeof(u32)) { 946 err = -EINVAL;
936 err = -EINVAL; 947 if (pglen > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
937 goto bad; 948 goto bad;
938 } 949 err = -ENOMEM;
939 pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS); 950 pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS);
940 if (!pg) { 951 if (!pg)
941 err = -ENOMEM;
942 goto bad; 952 goto bad;
943 }
944 pg->pgid = pgid; 953 pg->pgid = pgid;
945 pg->len = pglen; 954 pg->len = pglen;
946 for (j = 0; j < pglen; j++) 955 for (j = 0; j < pglen; j++)