ceph: fix error paths for corrupt osdmap messages
authorSage Weil <sage@newdream.net>
Mon, 21 Dec 2009 22:49:37 +0000 (14:49 -0800)
committerSage Weil <sage@newdream.net>
Tue, 22 Dec 2009 00:39:59 +0000 (16:39 -0800)
Both osdmap_decode() and osdmap_apply_incremental() should never return
NULL.

Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/osd_client.c
fs/ceph/osdmap.c

index 4bfe880d53c8a3266504ec4545039f75a20116e7..b474b3ad61f0616f7265e014e46320f13c9a884f 100644 (file)
@@ -910,6 +910,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
                                err = PTR_ERR(newmap);
                                goto bad;
                        }
+                       BUG_ON(!newmap);
                        if (newmap != osdc->osdmap) {
                                ceph_osdmap_destroy(osdc->osdmap);
                                osdc->osdmap = newmap;
@@ -946,6 +947,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
                                err = PTR_ERR(newmap);
                                goto bad;
                        }
+                       BUG_ON(!newmap);
                        oldmap = osdc->osdmap;
                        osdc->osdmap = newmap;
                        if (oldmap)
index 8c8ffe5ef7d4442105aecf333ff844c1ea60236a..a9416308de6f32d7c9a8c25fc72f10daeaa964ab 100644 (file)
@@ -200,6 +200,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                        size = sizeof(struct crush_bucket_straw);
                        break;
                default:
+                       err = -EINVAL;
                        goto bad;
                }
                BUG_ON(size == 0);
@@ -278,6 +279,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
                /* len */
                ceph_decode_32_safe(p, end, yes, bad);
 #if BITS_PER_LONG == 32
+               err = -EINVAL;
                if (yes > ULONG_MAX / sizeof(struct crush_rule_step))
                        goto bad;
 #endif
@@ -489,11 +491,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
                ceph_decode_copy(p, &pgid, sizeof(pgid));
                n = ceph_decode_32(p);
                ceph_decode_need(p, end, n * sizeof(u32), bad);
+               err = -ENOMEM;
                pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);
-               if (!pg) {
-                       err = -ENOMEM;
+               if (!pg)
                        goto bad;
-               }
                pg->pgid = pgid;
                pg->len = n;
                for (j = 0; j < n; j++)
@@ -564,8 +565,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        if (len > 0) {
                dout("apply_incremental full map len %d, %p to %p\n",
                     len, *p, end);
-               newmap = osdmap_decode(p, min(*p+len, end));
-               return newmap;  /* error or not */
+               return osdmap_decode(p, min(*p+len, end));
        }
 
        /* new crush? */
@@ -809,6 +809,7 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol,
        struct ceph_pg_pool_info *pool;
        unsigned ps;
 
+       BUG_ON(!osdmap);
        if (poolid >= osdmap->num_pools)
                return -EIO;