From fc32c65953b472bf46cc20e79e30d7c0ab35116f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 17 Mar 2008 11:13:25 -0700 Subject: [PATCH] client: redid mdsmap decoding --- src/kernel/decode.h | 9 +++++++ src/kernel/mdsmap.c | 66 +++++++++++++++++++++------------------------ src/kernel/osdmap.c | 8 ++++-- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/src/kernel/decode.h b/src/kernel/decode.h index 835b4232e7e04..82ead5e5951da 100644 --- a/src/kernel/decode.h +++ b/src/kernel/decode.h @@ -1,6 +1,15 @@ #ifndef __CEPH_DECODE_H #define __CEPH_DECODE_H +/* + * in all cases, + * void **p pointer to position pointer + * void *end pointer to end of buffer (last byte + 1) + */ + +/* + * bounds check input. + */ #define ceph_decode_need(p, end, n, bad) \ do { \ if (unlikely(*(p) + (n) > (end))) \ diff --git a/src/kernel/mdsmap.c b/src/kernel/mdsmap.c index b734f33b3974f..7402ee27e7106 100644 --- a/src/kernel/mdsmap.c +++ b/src/kernel/mdsmap.c @@ -6,6 +6,7 @@ #include "mdsmap.h" #include "messenger.h" +#include "decode.h" int ceph_mdsmap_debug = 50; #define DOUT_VAR ceph_mdsmap_debug @@ -55,69 +56,62 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) struct ceph_mdsmap *m; int i, n; __u32 mds; - int err; + int err = -EINVAL; m = kzalloc(sizeof(*m), GFP_KERNEL); if (m == NULL) return ERR_PTR(-ENOMEM); - if ((err = ceph_decode_32(p, end, &m->m_epoch)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_client_epoch)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_created.tv_sec)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_created.tv_usec)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_anchortable)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_root)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_cap_bit_timeout)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_session_autoclose)) != 0) - goto bad; - if ((err = ceph_decode_32(p, end, &m->m_max_mds)) != 0) - goto bad; + ceph_decode_need(p, end, 10*sizeof(__u32), bad); + ceph_decode_32(p, m->m_epoch); + ceph_decode_32(p, m->m_client_epoch); + ceph_decode_32(p, m->m_created.tv_sec); + ceph_decode_32(p, m->m_created.tv_usec); + ceph_decode_32(p, m->m_anchortable); + ceph_decode_32(p, m->m_root); + ceph_decode_32(p, m->m_cap_bit_timeout); + ceph_decode_32(p, m->m_session_autoclose); + ceph_decode_32(p, m->m_max_mds); m->m_addr = kmalloc(m->m_max_mds*sizeof(*m->m_addr), GFP_KERNEL); m->m_state = kzalloc(m->m_max_mds*sizeof(*m->m_state), GFP_KERNEL); + if (m->m_addr == NULL || m->m_state == NULL) + goto badmem; /* state */ - if ((err = ceph_decode_32(p, end, &n)) != 0) - goto bad; + ceph_decode_32(p, n); + ceph_decode_need(p, end, n*2*sizeof(__u32), bad); for (i=0; i= m->m_max_mds) goto bad; - if ((err = ceph_decode_32(p, end, &m->m_state[mds])) != 0) - goto bad; + ceph_decode_32(p, m->m_state[mds]); } /* state_seq */ - if ((err = ceph_decode_32(p, end, &n)) != 0) - goto bad; + ceph_decode_32_safe(p, end, n, bad); *p += n*(sizeof(__u32)+sizeof(__u64)); /* mds_inst */ - if ((err = ceph_decode_32(p, end, &n)) != 0) - goto bad; + ceph_decode_32_safe(p, end, n, bad); + ceph_decode_need(p, end, + n*(sizeof(__u32)+sizeof(struct ceph_entity_name)+ + sizeof(struct ceph_entity_addr)), + bad); for (i=0; i= m->m_max_mds) goto bad; *p += sizeof(struct ceph_entity_name); - if ((err = ceph_decode_copy(p, end, &m->m_addr[mds], - sizeof(*m->m_addr))) != 0) - goto bad; + ceph_decode_copy(p, &m->m_addr[mds], sizeof(*m->m_addr)); } /* ok, we don't care about the rest. */ dout(30, "mdsmap_decode success epoch %u\n", m->m_epoch); return m; +badmem: + err = -ENOMEM; bad: derr(0, "corrupt mdsmap"); ceph_mdsmap_destroy(m); @@ -126,7 +120,7 @@ bad: void ceph_mdsmap_destroy(struct ceph_mdsmap *m) { - if (m->m_addr) kfree(m->m_addr); - if (m->m_state) kfree(m->m_state); + kfree(m->m_addr); + kfree(m->m_state); kfree(m); } diff --git a/src/kernel/osdmap.c b/src/kernel/osdmap.c index bda96b7f03b4b..6ddf0fdaa018d 100644 --- a/src/kernel/osdmap.c +++ b/src/kernel/osdmap.c @@ -485,7 +485,8 @@ bad: */ void calc_file_object_mapping(struct ceph_file_layout *layout, loff_t *off, loff_t *len, - struct ceph_object *oid, __u64 *oxoff, __u64 *oxlen) + struct ceph_object *oid, + __u64 *oxoff, __u64 *oxlen) { unsigned su, stripeno, stripepos, objsetno; unsigned su_per_object; @@ -544,7 +545,10 @@ void calc_object_layout(struct ceph_object_layout *ol, num = osdmap->pg_num; num_mask = osdmap->pg_num_mask; } - ol->ol_pgid.pg.ps = ceph_stable_mod(oid->bno + crush_hash32_2(oid->ino, oid->ino>>32), num, num_mask); + ol->ol_pgid.pg.ps = + ceph_stable_mod(oid->bno + crush_hash32_2(oid->ino, + oid->ino>>32), + num, num_mask); ol->ol_pgid.pg.preferred = fl->fl_pg_preferred; ol->ol_pgid.pg.type = fl->fl_pg_type; ol->ol_pgid.pg.size = fl->fl_pg_size; -- 2.39.5