aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
authorPatrick Caulfeld <pcaulfie@redhat.com>2008-01-17 05:25:28 -0500
committerDavid Teigland <teigland@redhat.com>2008-01-30 12:04:43 -0500
commit2a79289e87f3b6487b5fd23c8569f32097057fb4 (patch)
tree3b099a7b7306ee99fcb272e260b7344d34fdc666 /fs/dlm
parent85f0379aa0f9366bb6918e2e898a915231176fbd (diff)
dlm: Sanity check namelen before copying it
The 32/64 compatibility code in the DLM does not check the validity of the lock name length passed into it, so it can easily overwrite memory if the value is rubbish (as early versions of libdlm can cause with unlock calls, it doesn't zero the field). This patch restricts the length of the name to the amount of data actually passed into the call. Signed-off-by: Patrick Caulfield <pcaulfie@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/user.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index eb6164816948..1acb4c5813cd 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -82,7 +82,8 @@ struct dlm_lock_result32 {
82}; 82};
83 83
84static void compat_input(struct dlm_write_request *kb, 84static void compat_input(struct dlm_write_request *kb,
85 struct dlm_write_request32 *kb32) 85 struct dlm_write_request32 *kb32,
86 int max_namelen)
86{ 87{
87 kb->version[0] = kb32->version[0]; 88 kb->version[0] = kb32->version[0];
88 kb->version[1] = kb32->version[1]; 89 kb->version[1] = kb32->version[1];
@@ -112,7 +113,11 @@ static void compat_input(struct dlm_write_request *kb,
112 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; 113 kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
113 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; 114 kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
114 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); 115 memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
115 memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen); 116 if (kb->i.lock.namelen <= max_namelen)
117 memcpy(kb->i.lock.name, kb32->i.lock.name,
118 kb->i.lock.namelen);
119 else
120 kb->i.lock.namelen = max_namelen;
116 } 121 }
117} 122}
118 123
@@ -529,7 +534,8 @@ static ssize_t device_write(struct file *file, const char __user *buf,
529 534
530 if (proc) 535 if (proc)
531 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); 536 set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
532 compat_input(kbuf, k32buf); 537 compat_input(kbuf, k32buf,
538 count - sizeof(struct dlm_write_request32));
533 kfree(k32buf); 539 kfree(k32buf);
534 } 540 }
535#endif 541#endif