Commit 2a79289e authored by Patrick Caulfeld's avatar Patrick Caulfeld Committed by David Teigland

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: default avatarPatrick Caulfield <pcaulfie@redhat.com>
Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
parent 85f0379a
...@@ -82,7 +82,8 @@ struct dlm_lock_result32 { ...@@ -82,7 +82,8 @@ struct dlm_lock_result32 {
}; };
static void compat_input(struct dlm_write_request *kb, static void compat_input(struct dlm_write_request *kb,
struct dlm_write_request32 *kb32) struct dlm_write_request32 *kb32,
int max_namelen)
{ {
kb->version[0] = kb32->version[0]; kb->version[0] = kb32->version[0];
kb->version[1] = kb32->version[1]; kb->version[1] = kb32->version[1];
...@@ -112,7 +113,11 @@ static void compat_input(struct dlm_write_request *kb, ...@@ -112,7 +113,11 @@ static void compat_input(struct dlm_write_request *kb,
kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr; kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb; kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN); memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
memcpy(kb->i.lock.name, kb32->i.lock.name, kb->i.lock.namelen); if (kb->i.lock.namelen <= max_namelen)
memcpy(kb->i.lock.name, kb32->i.lock.name,
kb->i.lock.namelen);
else
kb->i.lock.namelen = max_namelen;
} }
} }
...@@ -529,7 +534,8 @@ static ssize_t device_write(struct file *file, const char __user *buf, ...@@ -529,7 +534,8 @@ static ssize_t device_write(struct file *file, const char __user *buf,
if (proc) if (proc)
set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags); set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
compat_input(kbuf, k32buf); compat_input(kbuf, k32buf,
count - sizeof(struct dlm_write_request32));
kfree(k32buf); kfree(k32buf);
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment