]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix monmap buffer overrun
authorSage Weil <sage@newdream.net>
Thu, 16 Jul 2009 23:46:11 +0000 (16:46 -0700)
committerSage Weil <sage@newdream.net>
Fri, 17 Jul 2009 20:53:38 +0000 (13:53 -0700)
Find num_mon before allocating monmap, so we get the right amount
of memory.

src/kernel/mon_client.c
src/kernel/mon_client.h

index 5d291117d184699b01c77d553e997e38b9ae2b4e..9abb45bea6d92b567b934b8a4faf44a2e2088410 100644 (file)
  */
 struct ceph_monmap *ceph_monmap_decode(void *p, void *end)
 {
-       struct ceph_monmap *m;
+       struct ceph_monmap *m = 0;
        int i, err = -EINVAL;
        ceph_fsid_t fsid;
+       u32 epoch, num_mon;
 
        dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p));
 
+       ceph_decode_need(&p, end, 2*sizeof(u32) + 2*sizeof(u64), bad);
+       ceph_decode_copy(&p, &fsid, sizeof(fsid));
+       ceph_decode_32(&p, epoch);
+       ceph_decode_32(&p, num_mon);
+       ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad);
+
        /* The encoded and decoded sizes match. */
-       m = kmalloc(end-p, GFP_NOFS);
+       m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS);
        if (m == NULL)
                return ERR_PTR(-ENOMEM);
+       m->fsid = fsid;
+       m->epoch = epoch;
+       m->num_mon = num_mon;
+       ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0]));
 
-       ceph_decode_need(&p, end, 2*sizeof(u32) + 2*sizeof(u64), bad);
-       ceph_decode_copy(&p, &m->fsid, sizeof(fsid));
-       ceph_decode_32(&p, m->epoch);
-       ceph_decode_32(&p, m->num_mon);
-       ceph_decode_need(&p, end, m->num_mon*sizeof(m->mon_inst[0]), bad);
-       ceph_decode_copy(&p, m->mon_inst, m->num_mon*sizeof(m->mon_inst[0]));
        if (p != end)
                goto bad;
 
index 027e0646513472bf4154ef5faa0be7eb341059b5..fad8e7513192c5d2877f4645004ac6a736e963b1 100644 (file)
@@ -24,9 +24,6 @@ struct ceph_mount_args;
 
 /*
  * The monitor map enumerates the set of all monitors.
- *
- * Make sure this structure size matches the encoded map size, or change
- * ceph_monmap_decode().
  */
 struct ceph_monmap {
        ceph_fsid_t fsid;