diff options
Diffstat (limited to 'fs/ceph/mdsmap.c')
| -rw-r--r-- | fs/ceph/mdsmap.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index 97ecf272a37d..c91c0e2e118b 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -3,6 +3,7 @@ #include <linux/bug.h> #include <linux/err.h> +#include <linux/overflow.h> #include <linux/random.h> #include <linux/slab.h> #include <linux/types.h> @@ -126,6 +127,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, u8 mdsmap_v; u16 mdsmap_ev; u32 target; + size_t export_targets_len; m = kzalloc(sizeof(*m), GFP_NOFS); if (!m) @@ -224,8 +226,11 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, *p += namelen; if (info_v >= 2) { ceph_decode_32_safe(p, end, num_export_targets, bad); + export_targets_len = size_mul(num_export_targets, + sizeof(u32)); + ceph_decode_need(p, end, export_targets_len, bad); pexport_targets = *p; - *p += num_export_targets * sizeof(u32); + *p += export_targets_len; } else { num_export_targets = 0; } @@ -264,6 +269,10 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, goto nomem; for (j = 0; j < num_export_targets; j++) { target = ceph_decode_32(&pexport_targets); + if (target >= CEPH_MAX_MDS) { + err = -EIO; + goto corrupt; + } info->export_targets[j] = target; } } else { |
