aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/dir.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-01-25 04:08:09 -0500
committerDavid Teigland <teigland@redhat.com>2008-02-04 02:24:52 -0500
commitcd9df1aac346f1c7f592739d092ff710c27bbcde (patch)
treecc7eadf1e209742b89cb0a064495dee9f1fc6c98 /fs/dlm/dir.c
parent02ed16b64dc5b7a4f78476bdb64da9bbf88d84b3 (diff)
dlm: validate data in dlm_recover_directory()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm/dir.c')
-rw-r--r--fs/dlm/dir.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c
index ce30136671b3..831050e5bfd5 100644
--- a/fs/dlm/dir.c
+++ b/fs/dlm/dir.c
@@ -220,6 +220,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
220 last_len = 0; 220 last_len = 0;
221 221
222 for (;;) { 222 for (;;) {
223 int left;
223 error = dlm_recovery_stopped(ls); 224 error = dlm_recovery_stopped(ls);
224 if (error) 225 if (error)
225 goto out_free; 226 goto out_free;
@@ -236,11 +237,20 @@ int dlm_recover_directory(struct dlm_ls *ls)
236 */ 237 */
237 238
238 b = ls->ls_recover_buf->rc_buf; 239 b = ls->ls_recover_buf->rc_buf;
240 left = ls->ls_recover_buf->rc_header.h_length;
241 left -= sizeof(struct dlm_rcom);
239 242
240 for (;;) { 243 for (;;) {
241 memcpy(&namelen, b, sizeof(uint16_t)); 244 __be16 v;
242 namelen = be16_to_cpu(namelen); 245
243 b += sizeof(uint16_t); 246 error = -EINVAL;
247 if (left < sizeof(__be16))
248 goto out_free;
249
250 memcpy(&v, b, sizeof(__be16));
251 namelen = be16_to_cpu(v);
252 b += sizeof(__be16);
253 left -= sizeof(__be16);
244 254
245 /* namelen of 0xFFFFF marks end of names for 255 /* namelen of 0xFFFFF marks end of names for
246 this node; namelen of 0 marks end of the 256 this node; namelen of 0 marks end of the
@@ -251,6 +261,12 @@ int dlm_recover_directory(struct dlm_ls *ls)
251 if (!namelen) 261 if (!namelen)
252 break; 262 break;
253 263
264 if (namelen > left)
265 goto out_free;
266
267 if (namelen > DLM_RESNAME_MAXLEN)
268 goto out_free;
269
254 error = -ENOMEM; 270 error = -ENOMEM;
255 de = get_free_de(ls, namelen); 271 de = get_free_de(ls, namelen);
256 if (!de) 272 if (!de)
@@ -262,6 +278,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
262 memcpy(de->name, b, namelen); 278 memcpy(de->name, b, namelen);
263 memcpy(last_name, b, namelen); 279 memcpy(last_name, b, namelen);
264 b += namelen; 280 b += namelen;
281 left -= namelen;
265 282
266 add_entry_to_hash(ls, de); 283 add_entry_to_hash(ls, de);
267 count++; 284 count++;