diff options
| -rw-r--r-- | fs/ceph/mdsmap.c | 43 | ||||
| -rw-r--r-- | fs/ceph/super.c | 5 |
2 files changed, 36 insertions, 12 deletions
diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index 261531e55e9d..8c3591a7fbae 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c | |||
| @@ -54,16 +54,21 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) | |||
| 54 | const void *start = *p; | 54 | const void *start = *p; |
| 55 | int i, j, n; | 55 | int i, j, n; |
| 56 | int err = -EINVAL; | 56 | int err = -EINVAL; |
| 57 | u16 version; | 57 | u8 mdsmap_v, mdsmap_cv; |
| 58 | 58 | ||
| 59 | m = kzalloc(sizeof(*m), GFP_NOFS); | 59 | m = kzalloc(sizeof(*m), GFP_NOFS); |
| 60 | if (m == NULL) | 60 | if (m == NULL) |
| 61 | return ERR_PTR(-ENOMEM); | 61 | return ERR_PTR(-ENOMEM); |
| 62 | 62 | ||
| 63 | ceph_decode_16_safe(p, end, version, bad); | 63 | ceph_decode_need(p, end, 1 + 1, bad); |
| 64 | if (version > 3) { | 64 | mdsmap_v = ceph_decode_8(p); |
| 65 | pr_warn("got mdsmap version %d > 3, failing", version); | 65 | mdsmap_cv = ceph_decode_8(p); |
| 66 | goto bad; | 66 | if (mdsmap_v >= 4) { |
| 67 | u32 mdsmap_len; | ||
| 68 | ceph_decode_32_safe(p, end, mdsmap_len, bad); | ||
| 69 | if (end < *p + mdsmap_len) | ||
| 70 | goto bad; | ||
| 71 | end = *p + mdsmap_len; | ||
| 67 | } | 72 | } |
| 68 | 73 | ||
| 69 | ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad); | 74 | ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad); |
| @@ -87,16 +92,29 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) | |||
| 87 | u32 namelen; | 92 | u32 namelen; |
| 88 | s32 mds, inc, state; | 93 | s32 mds, inc, state; |
| 89 | u64 state_seq; | 94 | u64 state_seq; |
| 90 | u8 infoversion; | 95 | u8 info_v; |
| 96 | void *info_end = NULL; | ||
| 91 | struct ceph_entity_addr addr; | 97 | struct ceph_entity_addr addr; |
| 92 | u32 num_export_targets; | 98 | u32 num_export_targets; |
| 93 | void *pexport_targets = NULL; | 99 | void *pexport_targets = NULL; |
| 94 | struct ceph_timespec laggy_since; | 100 | struct ceph_timespec laggy_since; |
| 95 | struct ceph_mds_info *info; | 101 | struct ceph_mds_info *info; |
| 96 | 102 | ||
| 97 | ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad); | 103 | ceph_decode_need(p, end, sizeof(u64) + 1, bad); |
| 98 | global_id = ceph_decode_64(p); | 104 | global_id = ceph_decode_64(p); |
| 99 | infoversion = ceph_decode_8(p); | 105 | info_v= ceph_decode_8(p); |
| 106 | if (info_v >= 4) { | ||
| 107 | u32 info_len; | ||
| 108 | u8 info_cv; | ||
| 109 | ceph_decode_need(p, end, 1 + sizeof(u32), bad); | ||
| 110 | info_cv = ceph_decode_8(p); | ||
| 111 | info_len = ceph_decode_32(p); | ||
| 112 | info_end = *p + info_len; | ||
| 113 | if (info_end > end) | ||
| 114 | goto bad; | ||
| 115 | } | ||
| 116 | |||
| 117 | ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad); | ||
| 100 | *p += sizeof(u64); | 118 | *p += sizeof(u64); |
| 101 | namelen = ceph_decode_32(p); /* skip mds name */ | 119 | namelen = ceph_decode_32(p); /* skip mds name */ |
| 102 | *p += namelen; | 120 | *p += namelen; |
| @@ -115,7 +133,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) | |||
| 115 | *p += sizeof(u32); | 133 | *p += sizeof(u32); |
| 116 | ceph_decode_32_safe(p, end, namelen, bad); | 134 | ceph_decode_32_safe(p, end, namelen, bad); |
| 117 | *p += namelen; | 135 | *p += namelen; |
| 118 | if (infoversion >= 2) { | 136 | if (info_v >= 2) { |
| 119 | ceph_decode_32_safe(p, end, num_export_targets, bad); | 137 | ceph_decode_32_safe(p, end, num_export_targets, bad); |
| 120 | pexport_targets = *p; | 138 | pexport_targets = *p; |
| 121 | *p += num_export_targets * sizeof(u32); | 139 | *p += num_export_targets * sizeof(u32); |
| @@ -123,6 +141,12 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) | |||
| 123 | num_export_targets = 0; | 141 | num_export_targets = 0; |
| 124 | } | 142 | } |
| 125 | 143 | ||
| 144 | if (info_end && *p != info_end) { | ||
| 145 | if (*p > info_end) | ||
| 146 | goto bad; | ||
| 147 | *p = info_end; | ||
| 148 | } | ||
| 149 | |||
| 126 | dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n", | 150 | dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n", |
| 127 | i+1, n, global_id, mds, inc, | 151 | i+1, n, global_id, mds, inc, |
| 128 | ceph_pr_addr(&addr.in_addr), | 152 | ceph_pr_addr(&addr.in_addr), |
| @@ -163,6 +187,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) | |||
| 163 | m->m_cas_pg_pool = ceph_decode_64(p); | 187 | m->m_cas_pg_pool = ceph_decode_64(p); |
| 164 | 188 | ||
| 165 | /* ok, we don't care about the rest. */ | 189 | /* ok, we don't care about the rest. */ |
| 190 | *p = end; | ||
| 166 | dout("mdsmap_decode success epoch %u\n", m->m_epoch); | 191 | dout("mdsmap_decode success epoch %u\n", m->m_epoch); |
| 167 | return m; | 192 | return m; |
| 168 | 193 | ||
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 452770dc9fc1..d714ab20ad24 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
| @@ -519,9 +519,8 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, | |||
| 519 | { | 519 | { |
| 520 | struct ceph_fs_client *fsc; | 520 | struct ceph_fs_client *fsc; |
| 521 | const u64 supported_features = | 521 | const u64 supported_features = |
| 522 | CEPH_FEATURE_FLOCK | | 522 | CEPH_FEATURE_FLOCK | CEPH_FEATURE_DIRLAYOUTHASH | |
| 523 | CEPH_FEATURE_DIRLAYOUTHASH | | 523 | CEPH_FEATURE_MDSENC | CEPH_FEATURE_MDS_INLINE_DATA; |
| 524 | CEPH_FEATURE_MDS_INLINE_DATA; | ||
| 525 | const u64 required_features = 0; | 524 | const u64 required_features = 0; |
| 526 | int page_count; | 525 | int page_count; |
| 527 | size_t size; | 526 | size_t size; |
