libceph: check length of osdmap osd arrays
authorIlya Dryomov <ilya.dryomov@inktank.com>
Thu, 13 Mar 2014 14:36:14 +0000 (16:36 +0200)
committerSage Weil <sage@inktank.com>
Sat, 5 Apr 2014 04:07:41 +0000 (21:07 -0700)
Check length of osd_state, osd_weight and osd_addr arrays.  They
should all have exactly max_osd elements after the call to
osdmap_set_max_osd().

Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
Reviewed-by: Alex Elder <elder@linaro.org>
net/ceph/osdmap.c

index ec06010..c39ac62 100644 (file)
@@ -745,19 +745,25 @@ static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map)
        if (err)
                goto bad;
 
-       /* osds */
+       /* osd_state, osd_weight, osd_addrs->client_addr */
        ceph_decode_need(p, end, 3*sizeof(u32) +
                         map->max_osd*(1 + sizeof(*map->osd_weight) +
                                       sizeof(*map->osd_addr)), e_inval);
 
-       *p += 4; /* skip length field (should match max) */
+       if (ceph_decode_32(p) != map->max_osd)
+               goto e_inval;
+
        ceph_decode_copy(p, map->osd_state, map->max_osd);
 
-       *p += 4; /* skip length field (should match max) */
+       if (ceph_decode_32(p) != map->max_osd)
+               goto e_inval;
+
        for (i = 0; i < map->max_osd; i++)
                map->osd_weight[i] = ceph_decode_32(p);
 
-       *p += 4; /* skip length field (should match max) */
+       if (ceph_decode_32(p) != map->max_osd)
+               goto e_inval;
+
        ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr));
        for (i = 0; i < map->max_osd; i++)
                ceph_decode_addr(&map->osd_addr[i]);