[PATCH 07/16] dlm: validate data in dlm_recover_directory()

2008-02-06 Thread David Teigland
From: Al Viro <[EMAIL PROTECTED]>

Signed-off-by: Al Viro <[EMAIL PROTECTED]>
Signed-off-by: David Teigland <[EMAIL PROTECTED]>
---
 fs/dlm/dir.c |   23 ---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c
index ce30136..831050e 100644
--- a/fs/dlm/dir.c
+++ b/fs/dlm/dir.c
@@ -220,6 +220,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
last_len = 0;
 
for (;;) {
+   int left;
error = dlm_recovery_stopped(ls);
if (error)
goto out_free;
@@ -236,11 +237,20 @@ int dlm_recover_directory(struct dlm_ls *ls)
 */
 
b = ls->ls_recover_buf->rc_buf;
+   left = ls->ls_recover_buf->rc_header.h_length;
+   left -= sizeof(struct dlm_rcom);
 
for (;;) {
-   memcpy(, b, sizeof(uint16_t));
-   namelen = be16_to_cpu(namelen);
-   b += sizeof(uint16_t);
+   __be16 v;
+
+   error = -EINVAL;
+   if (left < sizeof(__be16))
+   goto out_free;
+
+   memcpy(, b, sizeof(__be16));
+   namelen = be16_to_cpu(v);
+   b += sizeof(__be16);
+   left -= sizeof(__be16);
 
/* namelen of 0xF marks end of names for
   this node; namelen of 0 marks end of the
@@ -251,6 +261,12 @@ int dlm_recover_directory(struct dlm_ls *ls)
if (!namelen)
break;
 
+   if (namelen > left)
+   goto out_free;
+
+   if (namelen > DLM_RESNAME_MAXLEN)
+   goto out_free;
+
error = -ENOMEM;
de = get_free_de(ls, namelen);
if (!de)
@@ -262,6 +278,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
memcpy(de->name, b, namelen);
memcpy(last_name, b, namelen);
b += namelen;
+   left -= namelen;
 
add_entry_to_hash(ls, de);
count++;
-- 
1.5.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 07/16] dlm: validate data in dlm_recover_directory()

2008-02-06 Thread David Teigland
From: Al Viro [EMAIL PROTECTED]

Signed-off-by: Al Viro [EMAIL PROTECTED]
Signed-off-by: David Teigland [EMAIL PROTECTED]
---
 fs/dlm/dir.c |   23 ---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c
index ce30136..831050e 100644
--- a/fs/dlm/dir.c
+++ b/fs/dlm/dir.c
@@ -220,6 +220,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
last_len = 0;
 
for (;;) {
+   int left;
error = dlm_recovery_stopped(ls);
if (error)
goto out_free;
@@ -236,11 +237,20 @@ int dlm_recover_directory(struct dlm_ls *ls)
 */
 
b = ls-ls_recover_buf-rc_buf;
+   left = ls-ls_recover_buf-rc_header.h_length;
+   left -= sizeof(struct dlm_rcom);
 
for (;;) {
-   memcpy(namelen, b, sizeof(uint16_t));
-   namelen = be16_to_cpu(namelen);
-   b += sizeof(uint16_t);
+   __be16 v;
+
+   error = -EINVAL;
+   if (left  sizeof(__be16))
+   goto out_free;
+
+   memcpy(v, b, sizeof(__be16));
+   namelen = be16_to_cpu(v);
+   b += sizeof(__be16);
+   left -= sizeof(__be16);
 
/* namelen of 0xF marks end of names for
   this node; namelen of 0 marks end of the
@@ -251,6 +261,12 @@ int dlm_recover_directory(struct dlm_ls *ls)
if (!namelen)
break;
 
+   if (namelen  left)
+   goto out_free;
+
+   if (namelen  DLM_RESNAME_MAXLEN)
+   goto out_free;
+
error = -ENOMEM;
de = get_free_de(ls, namelen);
if (!de)
@@ -262,6 +278,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
memcpy(de-name, b, namelen);
memcpy(last_name, b, namelen);
b += namelen;
+   left -= namelen;
 
add_entry_to_hash(ls, de);
count++;
-- 
1.5.3.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/